2010-04-18 17 views
14
  • बनाम क्या तेज है?

स्विच बयान लगभग 30 case रों होता मैं निम्नलिखित कर सकता है 30.सी ++ समारोह संकेत स्विच

0 से enumarated अहस्ताक्षरित ints से मिलकर,:

class myType 
{ 
    FunctionEnum func; 
    string argv[123]; 
    int someOtherValue; 
}; 
// In another file: 
myType current; 
// Iterate through a vector containing lots of myTypes 
// ... for (i=0; i < myVecSize; i ++) 
    switch (current.func) 
    { 
      case 1: 
      //... 
      break; 
      // ........ 
      case 30: 
      // blah 
      break; 
    } 

और func के साथ स्विच गर्त जाना हर बार। स्विच के बारे में अच्छी बात यह भी होगी कि मेरा कोड 30 कार्यों के मुकाबले अधिक व्यवस्थित है।

या मुझे लगता है कि (ताकि के साथ यकीन नहीं) कर सकता है:

class myType 
{ 
    myReturnType (*func)(int all, int of, int my, int args); 
    string argv[123]; 
    int someOtherValue; 
}; 

मैं 30 विभिन्न कार्यों तो होगा, शुरुआत में उनमें से एक के लिए एक सूचक MyType को सौंपा गया है।

  • शायद तेज़ क्या है: स्विच स्टेटमेंट या फ़ंक्शन पॉइंटर? प्रति सेकंड

कॉल: लगभग 10 लाख। मैं इसका परीक्षण नहीं कर सकता - मुझे पूरी चीज को फिर से लिखने की आवश्यकता होगी। वर्तमान में स्विच का उपयोग कर। हर घड़ी चक्र मायने रखता है -

मैं एक दुभाषिया जो मैं तेजी से होने के लिए अजगर & रूबी से चाहते हैं का निर्माण कर रहा हूँ!

+0

क्या आपका मतलब है 'myReturnType (* func)(); '? – kennytm

+0

@ केनीटीएम: भूल गए, हाँ। – Rawr

उत्तर

15

स्विच बयान आम तौर पर एक कूद की मेज के साथ लागू किया जाता है। मुझे लगता है कि असेंबली एक ही निर्देश पर जा सकती है, जो इसे बहुत तेज बना देगी।

एक ही तरीका है सुनिश्चित करने के लिए यह दोनों तरीकों से कोशिश करने के लिए है। यदि आप अपने मौजूदा कोड को संशोधित नहीं कर सकते हैं, तो क्यों न सिर्फ एक परीक्षण ऐप बनाएं और इसे आजमाएं?

+0

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

6

मुझे लगता है कि अंतर ज्यादातर मामलों में नगण्य है - आपके मामले एक अपवाद हो सकता है। प्रत्येक समाधान के प्रदर्शन को स्पष्ट रूप से मापने के लिए आप एक सरल प्रोटोटाइप ऐप क्यों नहीं डालते? मेरा अनुमान है कि इसे और अधिक काम के एक घंटे से भी नहीं ले जाएगा ...

हालांकि, स्पष्टता और कोड के रख-रखाव के बारे में सोचना भी है। आईएमएचओ यह स्पष्ट है कि फ़ंक्शन पॉइंटर समाधान इस संबंध में हाथ जीतता है।

अद्यतन: यह भी ध्यान रखें कि भले ही एक समाधान है, मान लें कि, दो बार के रूप में तेजी से अन्य के रूप में के रूप में यह है, यह अभी भी आवश्यक रूप से अपने कोड को फिर से लिखने का औचित्य साबित नहीं हो सकता हैं। आपको अपने एप को सबसे पहले यह निर्धारित करने के लिए प्रोफाइल करना चाहिए कि वास्तव में उन स्विच में निष्पादन समय कितना खर्च किया जाता है। यदि यह कुल समय का 50% है, तो इसे अनुकूलित करने का एक कारण है। यदि यह केवल कुछ पर्सेंट है, तो इसे अनुकूलित करने का प्रयास कचरा होगा।

+0

एकमात्र स्विच के मामले केवल 10-20 लाइन लंबी हैं। कार्य वास्तव में और अधिक पठनीय नहीं होगा। इसे लिखने में एक घंटे से अधिक समय लगेगा, शायद एक दिन - मेरे पास इतना समय नहीं है। मेरा प्रश्न वास्तव में मेरे ऐप के आर्किटेक्चर पर निर्भर नहीं है - यह केवल निम्नतम स्तर पर फ़ंक्शन पॉइंटर बनाम स्विच प्रदर्शन है। – Rawr

+0

अफसोस की बात है, आपने मुझे कुछ भी नया नहीं बताया: मुझे अपने ऐप के दो संस्करणों को परीक्षण, असंभव, और अकेले प्रोटोटाइप अकेले इसके अंत संस्करण को प्रतिबिंबित नहीं करेगा। – Rawr

+1

मैं पूरी तरह से कुछ खो रहा हूं, लेकिन मेरे विचार में परीक्षण ऐप को लगभग 3 कक्षाओं की आवश्यकता होगी: एक स्विच के साथ एक एकल वर्ग विधि का कार्यान्वयन, फ़ंक्शन पॉइंटर्स का उपयोग करने वाला दूसरा और एक टेस्ट क्लास (या यहां तक ​​कि 'मुख्य' विधि) जो प्रत्येक विधि को 10 मिलियन बार निष्पादित करती है और निष्पादन समय को मापती है। –

0

सी ++ में उस आकार के स्विच स्टेटमेंट आमतौर पर बेहतर वर्ग संगठन और बहुरूपता के उपयोग की आवश्यकता के व्यवस्थित होते हैं। क्या आप सुनिश्चित हैं कि कंपाइलर आपके लिए फ़ंक्शन कूद/गणना को संभालने के लिए अपना कोड करने का कोई तरीका नहीं है?

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

2

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

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

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

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

+0

अच्छी टिप्पणियां, एलन, लेकिन "हॉट स्पॉट" की अवधारणा वह है जो मुझे परेशान करती है। ऐसा लगता है कि पुराने विचार से यह पता चला है कि यदि बहुत अधिक समय बिताया जा रहा है, तो इसे एकमात्र रास्ता बढ़ाया जा सकता है, पीसी रजिस्टर द्वारा कुछ स्थानों में बहुत अधिक समय बिताया जाता है जिसे बदलने की जरूरत है। उस अवधारणा के आधार पर किसी भी प्रोफाइलर को मूर्ख बनाना बेहद आसान है, और कॉल ग्राफ बहुत बेहतर नहीं हैं। http://stackoverflow.com/questions/1777556/alternatives-to-gprof/1779343#1779343 –

0

लेखन दुभाषिया मजेदार है, है ना? मुझे लगता है कि फ़ंक्शन पॉइंटर तेज हो सकता है, लेकिन जब आप अनुकूलित कर रहे हैं, अनुमान आपको नहीं ले जाएंगे।

यदि आप वास्तव में उस जानवर से हर चक्र को चूसना चाहते हैं, तो यह कई पास ले जाएगा, और अनुमान आपको नहीं बताएंगे कि क्या ठीक करना है। Here's an example of what I mean.

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