2010-12-17 13 views
24

सी ++ प्रश्न यहां। मेरे पास एक प्रणाली है जहां मुझे दिए गए सुपरक्लास के सैकड़ों मिनी-सबक्लास हैं। उन सभी में एक "foo" विधि होगी जो कुछ करता है। या ... मेरे पास "टाइप" नामक एक पूर्णांक वाला एक वर्ग होगा और यह तय करने के लिए एक विशाल स्विच स्टेटमेंट का उपयोग करें कि मैं कब करूं।vftable प्रदर्शन जुर्माना बनाम स्विच स्टेटमेंट

प्रदर्शन यहां एक बड़ा विचार है। अत्यंत महत्वपूर्ण।

सवाल यह है कि स्विच स्टेटमेंट बनाम प्रदर्शन करने के प्रदर्शन लाभ/दंड क्या हैं? सी ++ इसे vftable के माध्यम से करते हैं? यदि मेरे पास स्विच स्टेटमेंट के रूप में है, तो मैं स्विच स्टेटमेंट के शीर्ष पर सामान्य रूप से प्रक्षेपित फू को ऊपर रख सकता हूं और तुलना में कम आम लोगों को उम्मीद कर सकता हूं। Vftable के साथ इस तरह का प्रभाव प्राप्त करने की कोशिश करने के लिए संकलक निर्भर है, भले ही मैं इसे कैसे समझूं ...

दूसरी ओर, मेरे कोड को इनके साथ निपटने के लिए बहुत आसान होगा बदसूरत स्विच स्टेटमेंट्स।

+3

शायद आपको मेटाप्रोग्रामिंग libs पर विचार करना चाहिए और देखें कि वे आपकी समस्या का समाधान कर सकते हैं या नहीं। –

+4

सी ++ कार्यकारी समूह ने सी ++ प्रदर्शन पर एक रिपोर्ट की और वर्चुअल फ़ंक्शंस के बारे में चिंताओं को संबोधित किया। लिंक देखें [यहां] (http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf) – sashang

+1

संकलक बयानों को पुन: व्यवस्थित करने के लिए स्वतंत्र है, जब तक कि पतन-माध्यम संरक्षित न हो , इस प्रकार आपके पास कोई गारंटी नहीं है (मानक से) कि सबसे लगातार मामलों का परीक्षण पहले किया जाएगा ... –

उत्तर

12

अगर मैं एक स्विच बयान के रूप में यह है, मैं आमतौर पर उत्पन्न foo के ऊपर स्विच बयान के ऊपर और नीचे कम आम लोगों में उम्मीद है कि तुलना shortcutting डाल सकते हैं,।

एक switch बयान आम तौर पर नहीं बल्कि if-else सशर्त, के एक ब्लॉक के रूप में अपने प्रश्न का तात्पर्य की तुलना में एक jump table को संकलित किया गया है। अभ्यास में, वर्चुअल टेबल और switch कूद तालिका में समान प्रदर्शन होना चाहिए, हालांकि परीक्षण करें कि आप वास्तव में चिंतित हैं।

+2

+1। नतीजा कार्यान्वयन-निर्भर है, इसलिए मापने का एकमात्र तरीका मापना है। – sharptooth

+2

+1: स्विच मूल रूप से वैसे भी एक vtable बन जाएगा। – Puppy

+1

जहां तक ​​मुझे पता है कि जंप टेबल का उपयोग x86 पर नहीं किया जाता है क्योंकि शाखाएं बहुत सस्ते होती हैं; एआरएम अभी भी उनका उपयोग करता है और उनके साथ निपटने के लिए विशिष्ट निर्देश हैं। –

0

लगभग सभी मामलों में Vtable तेज होना चाहिए, लेकिन यदि प्रदर्शन इतना महत्वपूर्ण है, तो पूछने की सही बात यह है कि कितना।

Vtable कॉल ट्रिपल इंडिकेशन (लक्ष्य कॉल पता प्राप्त करने के लिए तीन मेमोरी एक्सेस) है। यदि कई कॉल हैं तो कैश मिस एक मुद्दा नहीं होना चाहिए। तो, यह लगभग 2-3 स्विच लेबल तुलना है (हालांकि बाद में सीपीयू कैश मिस के लिए भी कम मौका प्रदान करता है, लेकिन पाइप उपयोग के लिए कम)।

आपको निश्चित रूप से यहां जो कुछ भी कहा गया है उस पर भरोसा नहीं करना चाहिए, और अपने लक्ष्य आर्किटेक्चर पर सही प्रदर्शन माप के साथ इसका परीक्षण करना चाहिए।

+2

आपको क्यों लगता है कि vtable तेज होना चाहिए? "परीक्षण और देखें कि तेज़ क्या है" के लिए – qdot

3

संकलक निर्धारित करता है कि स्विच स्टेटमेंट कैसे प्रबंधित किए जाते हैं, लेकिन उनके द्वारा उपयोग की जाने वाली कुछ बुनियादी तकनीकें हैं।

  1. अगर-किसी और बाइनरी-तरह: तुलना एन आइटम
  2. कूद तालिका का एक नक्शा में देखने के लिए अगर-बाकी लेकिन फैशन की तरह एक द्विआधारी-तरह में, प्रदर्शन इस प्रकार बराबर है की एक श्रृंखला के रूप में किया जाता है : यदि आइटम पर्याप्त रूप से पर्याप्त हैं तो पते की एक तालिका तैयार की जाएगी। लुकअप तब स्थिर समय में

जहां स्विच स्टेटमेंट में स्टेटमेंट स्टेटमेंट स्थित हैं, किसी भी मामले में कोई फर्क नहीं पड़ता है।

वर्चुअल फ़ंक्शंस में प्रत्यक्ष कॉल की तुलना में ओवरहेड होता है। इसमें एक अतिरिक्त ऑफ़सेट और पॉइंटर लुकअप शामिल है। सभी के लिए सबसे चरम प्रदर्शन विचारों के लिए यह लागत नगण्य है। एक स्विच की तुलना करते समय ओवरहेड आभासी लुकअप में नहीं है, लेकिन फ़ंक्शन स्वयं कॉल करता है। तो एक स्विच स्टेटमेंट जो प्रत्येक मामले में फ़ंक्शन को कॉल करता है, मूल रूप से वर्चुअल फ़ंक्शंस के समान ही प्रदर्शन करेगा।

इसलिए वर्चुअल फ़ंक्शन कॉल की तुलना में एक स्विच स्टेटमेंट (जंप टेबल के साथ) अनिवार्य रूप से "प्रेषण अर्थशास्त्र" लगभग अप्रासंगिक है। यदि आपके सभी "foo" विधियां अपेक्षाकृत छोटी हैं और इन्हें रेखांकित किया जा सकता है तो स्विच स्टेटमेंट बेहतर प्रदर्शन करना शुरू कर देगा। स्विच का दूसरा लाभ यह है कि आप स्विच से पहले सामान्य कोड डाल सकते हैं और बेहतर रजिस्टर/स्टैक अनुकूलन प्राप्त कर सकते हैं।

हालांकि, एक महत्वपूर्ण रखरखाव ओवरहेड है। इस बिंदु पर यह आपकी प्राथमिक चिंता होनी चाहिए। क्यूं कर? क्योंकि आपके कोड में प्रदर्शन बोतल-गर्दन स्विचिंग लॉगिन, या यहां तक ​​कि फ़ंक्शन कॉल की संभावना नहीं है, लेकिन कुछ और। जब तक आप कुछ और ठीक नहीं करते हैं, तब तक इन निम्न-स्तरीय प्रदर्शन समस्याओं को हल करने में कोई बात नहीं है। तो इस समय जो भी अधिक रखरखाव कोड प्रदान करता है उसके साथ चिपके रहें।

2

अन्य उत्तरों के लिए मैं दो और जोड़ दूंगा।

1) एक कंपाइलर के लिए एक वर्चुअल फ़ंक्शन कॉल इंटरफ़ेस में क्लासिक ऑप्टिमाइज़ेशन (अपंजीकरण सहित) को एक ही फ़ंक्शन में स्विच स्टेटमेंट में लेबल किए गए बयान के मुकाबले अधिक कठिन और कम आम है।

2) प्रेषण में कोई प्रदर्शन अंतर प्रोसेसर की शाखा भविष्यवाणी हार्डवेयर पर अत्यधिक निर्भर है। यहां तक ​​कि वर्चुअल फ़ंक्शन कॉल लक्ष्य पता (और वापसी) का सही ढंग से भविष्यवाणी की जा सकती है और आधुनिक आउट-ऑफ-ऑर्डर प्रोसेसर की पाइपलाइन में नगण्य प्रदर्शन ओवरहेड हो सकता है।

यदि इस ऑपरेशन का प्रदर्शन वास्तव में मायने रखता है, तो आपको वास्तव में वास्तविक प्रणाली के संदर्भ में इसे दोनों तरीकों का प्रयास करना और मापना होगा।

हैप्पी हैकिंग!

12

वर्चुअल मशीन डिज़ाइन के क्षेत्र में इस विषय पर कुछ शोध किया गया है। आम तौर पर, एक स्विच स्टेटमेंट तेजी से होने जा रहा है, वर्चुअल लुकअप के विपरीत बहुत सी वर्चुअल मशीन स्विच सेमेन्टिक्स का उपयोग करती हैं। सैद्धांतिक रूप से, कोई यह मान लेगा कि वर्चुअल टेबल - निरंतर समय एल्गोरिदम होने के नाते - तेज़ी से होगा, लेकिन हमें यह जांचना होगा कि हार्डवेयर वर्चुअल टेबल को कैसे देखता है।

कंपाइलर इनलाइन के लिए एक स्विच कथन आसान है। यह एक बड़ा विचार है, वर्चुअल फ़ंक्शन को कॉल करने का वास्तविक कार्य न्यूनतम है, हालांकि, पूरे स्टैक फ्रेम को धक्का देना और पॉप करना आवश्यक है क्योंकि संकलक को पता नहीं है कि रन-टाइम पर कौन सा फ़ंक्शन कॉल किया जाएगा।

शाखा पूर्वानुमान और हार्डवेयर प्रीफेच स्विच स्टेटमेंट पर आसान होना चाहिए, हालांकि आधुनिक आर्किटेक्चर वर्चुअल कॉल की भविष्यवाणी करने में बेहतर हो रहे हैं।

आभासी प्रेषण का उपयोग करने वाले बहुत से कोड ढेर आधारित आवंटन योजनाओं के उपयोग की आवश्यकता है। गतिशील स्मृति आवंटन बहुत सी ++ अनुप्रयोगों में एक बाधा है।

+0

इस विषय पर, यहां एंटोन एर्टल के मानदंड इस पर हैं: http://www.complang.tuwien.ac.at/ आगे/थ्रेडिंग/ –

+0

इसके अलावा, 'स्विच' के साथ, हम (1) स्पष्ट प्रकार की जानकारी (जहां व्यवहार्य सूचक छिपा हुआ है) (2) आसान सटीक वर्ग आकार नियंत्रण (3) और गैर-आभासी विनाशक हो सकता है। मुझे लगता है कि यह अनुकूलन में भी मदद करेगा। – Eonil

+1

वर्चुअल से इसकी झूठी ढेर की आवश्यकता है। ऑटो ऑब्जेक्ट्स वही काम करते हैं। और वस्तुओं को भी पूल किया। आप नए ओवरराइड कर सकते हैं और इसे स्थिर तालिका से भी आवंटित कर सकते हैं। –

संबंधित मुद्दे