2012-01-23 12 views
10

आज मैं एक ऐसी स्थिति में आया जहां मुझे यह तय करने की आवश्यकता थी कि लगभग 40 तत्वों वाली एक संपूर्ण संरचना शून्य है - जिसका अर्थ है कि प्रत्येक तत्व शून्य है।संरचना से तुलना करने के लिए पसंदीदा तरीका शून्य

  1. 40 बयान करता है, तो जिसके परिणामस्वरूप, शून्य करने के लिए प्रत्येक तत्व की तुलना:
    जब सोच है कि यह कैसे के रूप में तेजी से और संभव के रूप में कुशल बनाने के लिए, मैं ऐसा करने के लिए 3 अलग अलग तरीकों के बारे में सोचा।
  2. समान संरचना को आवंटित करना जो पहले ही शून्य हो गया है और memcmp संरचना के साथ है।
  3. एक संघ में संरचना को लपेटकर उसमें से सभी को कवर करने के लिए काफी बड़ा है।
उदाहरण

typedef union { 
    struct { 
    uint8_t a; 
    uint8_t b; 
    } 
    uint16_t c; 
} STRUCTURE_A; 

के लिए

और फिर शून्य के साथ उसकी तुलना।

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

+0

'if' कथन में पूरी संरचना को जांचने में क्या गलत है, जैसे कि आप शून्य ध्वज के लिए हो सकते हैं? –

+3

पैडिंग के बारे में मत भूलना! – NPE

+1

क्या आपने अपने तीन अलग-अलग तरीकों में से प्रत्येक को लागू किया है और उनके प्रदर्शन की तुलना की है? आपको क्या मिला? –

उत्तर

15

0.

के लिए संरचना के हर सदस्य की तुलना करें यह दो संरचनाओं वस्तुओं की तुलना करने के लिए (भले ही संरचना वस्तुओं में से एक सभी सदस्यों मान 0 पर सेट है) केवल सुरक्षित तरीका है। संरचना की तुलना करने के लिए memcmp का उपयोग न करें, संरचना में पैडिंग के बाइट्स का मान निर्दिष्ट नहीं है। ध्यान दें कि संरचना वस्तुओं के संचालन के साथ == ऑपरेटर का उपयोग करने की अनुमति नहीं है।

संरचना वस्तु तुलना पर इस सी-faq लिंक देखें:

Q: Is there a way to compare structures automatically?

+1

यदि आपने यह सुनिश्चित किया है कि संरचना में कोई पैडिंग नहीं है, तो 'memcmp' सुरक्षित है। जबकि एक कार्यान्वयन को तकनीकी रूप से मनमाने ढंग से गैर-कानूनी पैडिंग जोड़ने की अनुमति है, असली दुनिया में पैडिंग पूरी तरह से संरेखण के लिए है, और एक उचित ढंग से निर्मित, स्वाभाविक रूप से गठबंधन संरचना में अंत में संभावित रूप से कोई पैडिंग नहीं होगी। विशेष रूप से, 'intX_t' का उपयोग करके और संरेखण अंतराल के बिना उन्हें ऑर्डर करना किसी भी पैडिंग से बचने का एक अच्छा तरीका है। –

+0

यदि संरचना में कोई पैडिंग नहीं है, और 'memcmp' वास्तव में * तेज * है, तो अनुकूलक निश्चित रूप से उसको देखेगा और तदनुसार आपकी तुलना बदल देगा। –

+0

उम्मीद है ...... –

1

अपने संरचना आकार < = प्रोसेसर के वचन आकार है, तो आप अपने संघ चाल, हालांकि, किसी भी अच्छे संकलक क्या कर सकते हैं इसे स्वचालित रूप से करना चाहिए, उर्फ ​​यह if की कॉम्पैक्ट करेगा, स्पष्टता की अनुमति देता है लेकिन फिर भी प्रदर्शन को खरोंच तक रखता है।

0

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

गति के लिए, इस तरह से कुछ शुरू करें जो यह देखने के लिए प्रत्येक बाइट को जांचता है कि यह शून्य है या नहीं।

int iszero(void * ptr, int bytes) 
{ 
    char * bptr = (char*)ptr; 
    while(bytes--) 
    if(*bptr++) 
     return 0; 
    return 1; 
} 

फिर शब्द-संरेखित तुलना करने के लिए अनुकूलित करें। strlen() & memcpy() जैसी चीजों के उदाहरणों के लिए न्यूलिब के कार्यान्वयन की जांच करें।

+0

यह 'memcmp' के बराबर है और इसमें पैडिंग समस्याएं हो सकती हैं। –

+0

@ आर .. नहीं, यह memcmp() के बराबर नहीं है क्योंकि यहां कोई अपरिपक्वता शून्य संरचना नहीं है। Memcmp() में अतिरिक्त मेमोरी एक्सेस मेमोरी एक्सेस टाइम की तुलना में दोगुनी है क्योंकि आप हर बार दो पढ़ते हैं और आपके पास शायद बड़े ढांचे पर कैश कचरा होता है। मैंने पैडिंग समस्याओं पर विचार नहीं किया था। लेकिन अगर आपको पता है कि कोई पैडिंग नहीं है (उदा। प्राग पैक का उपयोग कर जीसीसी में), तो मैं अपने तर्क से खड़ा रहूंगा कि यह तकनीक सबसे तेज़ है। –

+0

"समकक्ष" से मेरा मतलब था कि इसका एक ही व्यवहार (और पैडिंग समस्या) है, लेकिन मैं आपको प्रदर्शन की तुलना करने के लिए आमंत्रित करता हूं। आपका कोड (बाइट-बाय-बाइट) इतना धीमा है कि कई पढ़ने के साथ भी, 'memcmp' जीतना चाहिए। एक अच्छा 'memcmp' एक समय में 4, 8, या यहां तक ​​कि 16 बाइट्स की तुलना करता है। बीटीडब्ल्यू "पैक" संरेखण के मुद्दों को ठीक करने का तरीका नहीं है। Ouah के जवाब पर मेरी टिप्पणी सही तरीका है। –

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