2011-12-19 17 views
6

मेरे पास कोड भर में कई स्थानों पर लॉगिंग फ़ंक्शन कहा जा रहा है। प्रत्येक लॉग में, मुझे 2 संकलन समय स्थिरांक प्रदान करना होगा।एक समारोह में संकलन समय स्थिरांक की आपूर्ति के लिए कौन सा दृष्टिकोण बेहतर है? फंक्शन तर्क बनाम टेम्पलेट पैरामीटर

(1) समारोह तर्क:

template<typename T> 
void log (const T &obj, const int LINE, const int COUNT) 
{ 
    // T is used for some purpose 
    if(debug) 
    logging(obj.out(), LINE, COUNT); 
} 

के रूप में यह कॉल,

log(str, __LINE__, __COUNTER__); 

(2) खाका पैरामीटर:

template<typename T, int LINE, int COUNT> 
void log (T &obj) 
{ 
    // T is used for some purpose 
    if(debug) 
    logging(obj.out(), LINE, COUNT); 
} 
वहाँ 2 दृष्टिकोण पूरा करने के लिए कर रहे हैं

इसे कॉल करें,

log<__LINE__, __COUNTER__>(str); 

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

अगर कोई व्यक्ति अपने अनुभव/ज्ञान से इसका उत्तर दे सकता है तो यह एक बड़ी मदद होगी।

+1

आप "बेहतर" कैसे परिभाषित करते हैं? वे दोनों * काम *, तो आप यह कहने के लिए किस मानदंड का उपयोग करेंगे कि एक दूसरे से बेहतर है? –

+0

@ निकोलबोलस, क्योंकि मैं संकलन समय और रनटाइम के आधार पर 2 के बीच बेहतर चुनना चाहता हूं। उदाहरण कोड में थोड़ा सा संशोधन भी है। – iammilind

+0

जो कुछ भी 'लॉगिंग' फ़ंक्शन करता है, वह निश्चित रूप से * दो पूर्णांक को तर्क के रूप में गुजरने से धीमा हो जाएगा। तो मुझे नहीं लगता कि रनटाइम प्रदर्शन कितना भी बदल जाएगा। यह एक समयपूर्व अनुकूलन की तरह संदिग्ध लगता है। –

उत्तर

3

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

+0

ठीक है, प्रश्न वाक्यविन्यास में थोड़ा सा संशोधन है। 'लॉग' स्वयं एक 'टेम्पलेट' फ़ंक्शन है, मैंने इसका उल्लेख नहीं करने का सोचा ...लेकिन पाया कि यह उपयोगी होगा। साथ ही, संकलक भी 'टेम्पलेट लॉग' के कई संस्करणों को अनुकूलित नहीं करेगा? – iammilind

+0

वैसे पहले पहले लॉग फ़ंक्शन, std :: string, std :: wstring, char *, wchar_t * के कुछ संस्करण होंगे। जबकि मूल रूप से प्रत्येक संस्करण को दूसरे संस्करण में कॉल करने के परिणामस्वरूप एक नया फ़ंक्शन होगा। ऑप्टिमाइज़र शायद इसे संभाल लेगा, लेकिन आपको लंबे संकलन समय के साथ एक ही परिणाम मिल जाएगा। – ronag

4

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

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

मैक्रो का एक अन्य संभावित लाभ: आप यह व्यवस्था कर सकते हैं कि पहला तर्क मूल्यांकन किया गया है और केवल तभी debug सत्य है। मुझे नहीं पता कि str का इंटरफ़ेस क्या है, या कहां से ऑब्जेक्ट आते हैं, लेकिन यदि log पर जाने के लिए सही मूल्य उत्पन्न करने के लिए कुछ भी लागत है, और फिर log गैर-डीबग मामले में इसका उपयोग नहीं करता है, तो यह रनटाइम का संभावित अपशिष्ट है।

+0

अच्छा जवाब ... अधिकांश समय LINE और COUNT का उपयोग नहीं किया जाएगा। उस मामले में फ़िर उत्पादन कोड कौन सा विकल्प बेहतर है? – iammilind

+0

@iammilind: यदि 'डीबग' एक संकलन-समय स्थिर है, और 'लॉग' पर कॉल रेखांकित है, तो उत्सर्जित कोड शायद वही तरीका होना चाहिए, हालांकि यह एक क्यूओआई मुद्दा है। यदि आप किसी विशेष कार्यान्वयन के विवरण जानना चाहते हैं, तो डिस्सेप्लर की जांच करें। –