2010-10-29 11 views
35

प्रश्न पढ़ने से पहले:
यह प्रश्न इस बात के बारे में नहीं है कि dynamic_cast का उपयोग करना कितना उपयोगी है। यह सिर्फ इसके प्रदर्शन के बारे में है।गतिशील_कास्ट का प्रदर्शन?

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

मैंने केवल इस पर विश्वास करने के बजाय इस विधि के प्रदर्शन का परीक्षण करने का फैसला किया।

निम्न कोड इस्तेमाल किया गया था:

ptime firstValue(microsec_clock::local_time()); 

ChildObject* castedObject = dynamic_cast<ChildObject*>(parentObject); 

ptime secondValue(microsec_clock::local_time()); 
time_duration diff = secondValue - firstValue; 
std::cout << "Cast1 lasts:\t" << diff.fractional_seconds() << " microsec" << std::endl; 

ऊपर कोड boost::date_time लिनक्स पर से तरीकों का उपयोग करता प्रयोग करने योग्य मूल्यों को प्राप्त करने के लिए।
मैंने एक निष्पादन में 3 dynamic_cast किया है, उन्हें मापने के लिए कोड समान है।

1 निष्पादन के परिणाम थे निम्नलिखित:
Cast1 रहता है: 74 माइक्रोसेक
Cast2 रहता है: 2 माइक्रोसेक
Cast3 रहता है: 1 माइक्रोसेक

पहले डाली हमेशा ले लिया 74-111 माइक्रोसेक, निम्नलिखित एक ही निष्पादन में रहता है 1-3 microsec लिया।

तो आखिर में मेरे प्रश्न:
dynamic_cast वास्तव में खराब प्रदर्शन कर रहा है?
टेस्ट्रेसल्ट के मुताबिक नहीं। क्या मेरा टेस्टकोड सही है?
इतने सारे डेवलपर्स क्यों सोचते हैं कि यह धीमा है यदि यह नहीं है?

+13

क्या मुझे कुछ याद आ रही है? मैं cast2 या cast3 के लिए कोई कोड नहीं देख सकता। – Flexo

+4

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

+3

कोड में बहुत से गतिशील_casts होने के कारण डिज़ाइन समस्याओं का एक निश्चित संकेतक है। –

उत्तर

42

सबसे पहले, आपको केवल कुछ पुनरावृत्तियों की तुलना में प्रदर्शन को मापने की आवश्यकता है, क्योंकि आपके परिणाम टाइमर के संकल्प का प्रभुत्व होगा। उदाहरण का प्रयास करें एक प्रतिनिधि तस्वीर बनाने के लिए 1 मिलियन +। साथ ही, यह परिणाम व्यर्थ है जब तक कि आप इसे किसी चीज़ के साथ तुलना नहीं करते हैं, यानी समकक्ष करने के बिना लेकिन गतिशील कास्टिंग के बिना।

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

डायनामिक कास्टिंग धीमा हो जाएगा, क्योंकि इसे ऑब्जेक्ट के लिए आरटीटीआई (रन-टाइम टाइप जानकारी) तालिका तक पहुंचने की आवश्यकता है, और जांचें कि कास्ट मान्य है। फिर, इसे सही तरीके से उपयोग करने के लिए, आपको त्रुटि-हैंडलिंग कोड जोड़ना होगा जो जांचता है कि लौटा हुआ पॉइंटर NULL है या नहीं। यह सब चक्र लेता है।

मैं जानता हूँ कि आप इस बारे में बात नहीं करना चाहता था, लेकिन "एक डिजाइन जहां dynamic_cast एक बहुत प्रयोग किया जाता है" शायद एक संकेत है कि आप कुछ गलत कर रहे हैं ...

+5

+1, लेकिन 10K पुनरावृत्तियों की संभावना पर्याप्त नहीं है। 100 मिलियन की तरह कुछ बेहतर है। – sharptooth

+0

@ शार्पतोथ: उचित बिंदु! –

+0

@ ओलिवर चार्ल्सवर्थ "... इसे सही तरीके से उपयोग करने के लिए, आपको त्रुटि-हैंडलिंग कोड जोड़ना होगा जो जांचता है कि लौटा हुआ पॉइंटर न्यूल है" आपके द्वारा उल्लेख किए जा रहे चेक का एक समान संस्करण मौजूद है किसी ऑब्जेक्ट का रनटाइम प्रकार, इसलिए यह कोई तर्क नहीं है। – spectre

24

प्रदर्शन के बिना अर्थहीन है समकक्ष कार्यक्षमता की तुलना। ज्यादातर लोग कहते हैं कि गतिशील व्यवहार की तुलना किए बिना गतिशील_कास्ट धीमा है। इस पर उन्हें बुलाओ। एक और तरीका रखें:

यदि 'काम' की आवश्यकता नहीं है, तो मैं कोड लिख सकता हूं जो आपके से तेज़ी से विफल हो जाता है।

गतिशील_कास्ट को लागू करने के कई तरीके हैं, और कुछ दूसरों की तुलना में तेज़ हैं। स्ट्रॉस्ट्रप ने उदाहरण के लिए primes to improve dynamic_cast का उपयोग करने के बारे में एक पेपर प्रकाशित किया। दुर्भाग्य से यह नियंत्रित करना असामान्य है कि आपका कंपाइलर कैसे कास्ट लागू करता है, लेकिन यदि प्रदर्शन वास्तव में आपके लिए मायने रखता है, तो आपके पास उस कंपाइलर पर नियंत्रण होता है जिसका आप उपयोग करते हैं।

हालांकि, का उपयोग नहीं कर dynamic_cast हमेशा इसे का उपयोग की तुलना में तेजी हो जाएगा - लेकिन अगर आप वास्तव में नहीं है dynamic_cast की जरूरत है, तो उसका उपयोग नहीं करते! यदि आपको गतिशील लुकअप की आवश्यकता है, तो कुछ ओवरहेड होगा, और फिर आप विभिन्न रणनीतियों की तुलना कर सकते हैं।

+4

+1। हां, बीटीडब्ल्यू हर जीवित व्यक्ति अंततः मर जाता है। इसका मतलब यह नहीं है कि जीवित रहने का बुरा विचार है। – sharptooth

4

यह कहने के लिए खेद है, लेकिन आपका परीक्षण यह निर्धारित करने के लिए लगभग बेकार है कि कास्ट धीमा है या नहीं। Microsecond संकल्प काफी अच्छे के पास कहीं भी नहीं है। हम एक ऑपरेशन के बारे में बात कर रहे हैं कि, यहां तक ​​कि सबसे खराब स्थिति परिदृश्य में, एक सामान्य पीसी पर 100 घड़ी की टिक, या 50 से कम नैनोसेकंड से अधिक नहीं लेना चाहिए।

इसमें कोई संदेह नहीं है कि गतिशील कास्ट स्थैतिक कलाकारों की तुलना में धीमी हो जाएगी या फिर से दोबारा डाली जाएगी, क्योंकि असेंबली स्तर पर, बाद वाले दो एक असाइनमेंट (वास्तव में तेज़, 1 घड़ी टिक का क्रम) होगा, और गतिशील कलाकार को कोड को जाने और वस्तु का वास्तविक प्रकार निर्धारित करने के लिए निरीक्षण करने की आवश्यकता होती है।

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

+0

डायनामिक_कास्ट को आरटीटीआई तक पहुंचने की ज़रूरत है, यह चक्र लेगा। – doron

16

यहाँ कुछ मानक हैं:
http://tinodidriksen.com/2010/04/14/cpp-dynamic-cast-performance/
http://www.nerdblog.com/2006/12/how-slow-is-dynamiccast.html

उनके मुताबिक, dynamic_cast 5-30 बार reinterpret_cast की तुलना में धीमी है, और सबसे अच्छा विकल्प reinterpret_cast के रूप में लगभग एक ही प्रदर्शन करती है।

मैं पहला लेख से निष्कर्ष बोली होगी:

  • dynamic_cast कुछ भी लेकिन आधार प्रकार के कास्टिंग के लिए धीमी गति से होता है; कि विशेष डाली बाहर अनुकूलित है
  • विरासत स्तर
  • सदस्य चर dynamic_cast पर एक बड़ा प्रभाव पड़ता है + reinterpret_cast
    प्रकार निर्धारित करने के सबसे तेजी से विश्वसनीय तरीका है, तथापि, कि एक बहुत उच्च रखरखाव उपरि
    जब कोडिंग

निरपेक्ष संख्या एक एकल कलाकारों के लिए 100 एनएस के आदेश पर हैं। 74 एमसीईसी जैसे मूल्य वास्तविकता के करीब नहीं लगते हैं।

+1

वह जो मूल्य प्राप्त कर रहा था वह 74 उपयोग (माइक्रोसॉन्ड) था, 74 एमसीसी (मिलीसेकंड) नहीं। फिर भी, यह अभी भी यथार्थवादी नहीं लगता है। – Ponkadoodle

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