2011-04-24 14 views
11

मेरे SAX xml पार्सिंग कॉलबैक (एक्सकोड 4, एलएलवीएम) में, मैं इस प्रकार के कोड पर बहुत सी कॉल कर रहा हूं:क्या मैं कॉन्स्ट char * पर स्ट्रेल को अनुकूलित करने के लिए अपने कंपाइलर पर भरोसा कर सकता हूं?

static const char* kFoo = "Bar"; 

void SaxCallBack(char* sax_string,.....) 
{ 
    if (strcmp(sax_string, kFoo, strlen(kFoo)) == 0) 
    { 

    } 


    } 

क्या यह मानना ​​सुरक्षित है कि स्ट्रेल (केएफयू) को संकलक द्वारा अनुकूलित किया गया है ?

(ऐप्पल नमूना कोड की पूर्व गणना की गई स्ट्रेल (केएफयू) थी, लेकिन मुझे लगता है कि यह लगातार स्ट्रिंग्स की बड़ी संख्या के लिए त्रुटि प्रवण है।)

संपादित करें: अनुकूलन के लिए प्रेरणा: आईपॉड पर मेरे एसवीजी मानचित्र को पार्स करना स्पर्श 2 जी NSXMLParser का उपयोग करके 5 सेकंड (!) लेता है। तो, मैं lib2xml पर स्विच करना चाहता हूं, और स्ट्रिंग तुलना को अनुकूलित करना चाहता हूं।

+0

शुरुआती लोगों को अनुकूलन सलाह: नहीं। विशेषज्ञों को अनुकूलन सलाह: अभी तक नहीं। जब तक प्रोफाइलिंग ने यह नहीं दिखाया है कि बोतल की गर्दन आपके कार्यक्रम में है, मुझे लगता है कि आपको इसके बारे में चिंता नहीं करनी चाहिए। – freespace

+2

आपका मतलब है 'strncmp', है ना? क्योंकि आप केवल 'strcmp' (दो तर्कों के साथ) का उपयोग कर सकते हैं और यह वर्तमान में लिखे गए शर्त के बराबर होगा। –

+4

@ फ्रीस्पेस सवाल यह है कि "क्या मैं अनुकूलित करने के लिए अपने कंपाइलर पर भरोसा कर सकता हूं ...?"। जब तक आपको लगता है कि यह सलाह कंपाइलर्स पर लागू नहीं होती है, तो मुझे नहीं लगता कि यह इस प्रश्न के लिए प्रासंगिक कैसे है। –

उत्तर

6

यदि "एलएलवीएम" से आपका मतलब क्लैंग है, तो हाँ, आप strlen दूर ऑप्टिमाइज़ करने के लिए clang -O पर भरोसा कर सकते हैं।

_SaxCallBack: 
Leh_func_begin1: 
    pushq %rbp 
Ltmp0: 
    movq %rsp, %rbp 
Ltmp1: 
    leaq L_.str1(%rip), %rsi 
    movl $3, %edx 
    callq _strncmp 
    ... 

मैं strncmp में strcmp बदल गया है, लेकिन तीसरा तर्क वास्तव में तत्काल $3 ने ले लिया है: यहाँ क्या अपने समारोह के लिए कोड की तरह लग रहा है।

ध्यान दें कि gcc 4.2.1 -O3 इस strlen कॉल को अनुकूलित नहीं करता है, और आप केवल अपने प्रश्न की सटीक स्थितियों में काम करने की उम्मीद कर सकते हैं (विशेष रूप से, स्ट्रिंग और strlen पर कॉल होना चाहिए फ़ाइल)।

+1

मैंने माइक्रोसॉफ्ट कंपाइलर की जांच की। यह '/ O2' ऑप्टिमाइज़ेशन का उपयोग करते समय कॉल को भी अनुकूलित करता है। –

+2

जीसीसी 'स्ट्रिंग()' कॉल को ऑप्टिमाइज़ करता है अगर 'केएफयू' स्वयं को 'कॉन्स्ट' बनाया जाता है (यानी 'स्थिर कॉन्स char * const kfoo = "bar"; ')। – caf

+0

'क्लैंग संस्करण 2.8' मेरी मशीन पर दूसरी' const' के बिना 'strlen()' को अनुकूलित नहीं करता है। – jfs

1

सामान्य रूप से आप इस पर भरोसा नहीं कर सकते हैं। हालांकि, आप 'sizeof' का उपयोग कर सकते हैं और इसे एक स्ट्रिंग अक्षर पर लागू कर सकते हैं। बेशक, इसका मतलब यह है कि आप मूल रूप से परिभाषित तरीके से 'केएफयू' को परिभाषित नहीं कर सकते हैं।

निम्नलिखित सभी कंपाइलरों और सभी अनुकूलन स्तरों पर काम करना चाहिए।

#define kFoo "..." 

    ... strcmp(... sizeof(kFoo)) 
+4

ध्यान दें कि इस मामले में 'sizeof (kFoo) == strlen (kFoo) + 1' ('आकार' में समाप्ति 'एनयूएल' शामिल है) – vladr

9

तरह बातें न लिखें: आप बना लिया है

static const char* kFoo = "Bar"; 

एक चरkFoo कि निरंतर डेटा को इंगित करता है नाम दिया है। संकलक यह पता लगाने में सक्षम हो सकता है कि यह चर बदलता नहीं है और इसे अनुकूलित करता है, लेकिन यदि नहीं, तो आपने अपने प्रोग्राम के डेटा सेगमेंट को फूला दिया है।

भी तरह बातें नहीं लिखते:

static const char *const kFoo = "Bar"; 

अब आप अपने चर kFooconst -qualified और गैर परिवर्तनीय है, लेकिन अगर यह स्थिति स्वतंत्र कोड में प्रयोग किया जाता है (साझा पुस्तकालयों आदि), सामग्री होगा अभी भी रनटाइम पर भिन्न होता है और इस प्रकार यह आपके प्रोग्राम में स्टार्टअप और मेमोरी लागत जोड़ देगा। इसके बजाय, का उपयोग करें:

static const char kFoo[] = "Bar"; 

या यहाँ तक कि:

#define kFoo "Bar" 
+0

कूल धन्यवाद आर !! – Jacko

+7

मैं सी ++ में '# परिभाषित' विकल्प की अनुशंसा नहीं करता, निश्चित रूप से नहीं! सूचक मुद्दे पर सिर के लिए धन्यवाद। –

+1

प्रश्न सी को टैग किया गया है, सी ++ नहीं। लेकिन हाँ, मैं वैसे भी 'स्थिर कॉन्स चार []' रूप पसंद करूंगा। –

0

फ़ॉलो-अप प्रश्न:

आप निम्नलिखित परीक्षण किया है?

static std::string const kFoo = "BAR"; 

void SaxCallBack(char* sax_string,.....) 
{ 
    if (sax_string == kFoo) 
    { 

    } 


} 

यह पठनीयता में शुद्ध जीत है, लेकिन मुझे प्रदर्शन लागत के बारे में कोई जानकारी नहीं है।

वैकल्पिक रूप से, यदि आपको स्वयं से प्रेषण करना है, तो मैंने पाया है कि एक राज्य-मशीन जैसे दृष्टिकोण (स्टैक के साथ) का उपयोग करना बेहतर पठनीयता-वार है, और प्रदर्शन के अनुसार भी जीत सकता है (बड़े होने की बजाय आपके पास स्विच करने के लिए टैग की संख्या में केवल टैग हैं जिन्हें अभी पूरा किया जा सकता है)।

+0

धन्यवाद, मैथ्यूयू। मैं रैगेल नामक एक राज्य मशीन जेनरेटर की तलाश में हूं, जो कई भाषाओं में पार्सर्स उत्पन्न कर सकता है। – Jacko

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

  • कोई संबंधित समस्या नहीं^_^