2012-03-22 17 views
11

के साथ .NET अनुप्रयोगों को प्रोफाइल करना ऐसा लगता है कि कोई निःशुल्क * .NET प्रदर्शन प्रोफ़ाइल नहीं है जो लाइन-दर-रेखा आधार पर प्रोफ़ाइल कर सकता है। इसलिए, मैं प्रोफाइलिंग के लिए स्टॉपवॉच का उपयोग करने में देख रहा हूं।स्टॉपवॉच

* स्वतंत्रता के रूप में निःशुल्क, यानी लाइसेंस में व्यावसायिक अनुप्रयोग शामिल हैं।

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

मेरे पास एक छोटा परीक्षण ऐप है (सी # में लिखा गया है) जो प्रति पंक्ति आधार पर स्टॉपवॉच का उपयोग करते समय प्रदर्शन अंतर को मापता है।

int n = 100; 
BigInteger f = 1; 
for (int i = n; i > 1; i--) 
{ 
    f *= i; 
} 

यहाँ पूर्ण कोड है:: परीक्षण कोड यह है http://pastebin.com/AvbQmT32

मैं कोड की प्रत्येक पंक्ति के लिए एक स्टॉपवॉच है। यह मेरा 'प्रोफाइलर' है। मेरे पास पूरे कार्यक्रम के लिए एक स्टॉपवॉच भी है। यह मेरा 'प्रोफाइलर प्रोफाइलर' है।

मेरे पास प्रोग्राम रिलीज़ मोड, किसी भी सीपीयू (x64 मशीन पर) के रूप में कॉन्फ़िगर किया गया है, और ऑप्टिमाइज़ेशन अक्षम हैं।

   Line    | Ticks 
------------------------------|---------- 
           | 
Total time:     |  359 

जब मैं इसे चलाने प्रोफाइलर के साथ सक्षम है, मैं कुछ इस तरह मिलती है::

   Line    | Ticks 
------------------------------|---------- 
           | 
int n = 100;     |   3 
BigInteger f = 1;    |  12 
for (int i = n; i > 1; i--) |  325 
{        | 
    f *= i;     |  539 
}        | 
           | 
Total time:     |  1710 
Stopwatch overhead:   |  831 

आदर्श रूप में

जब मैं प्रोफाइलर अक्षम के साथ कार्यक्रम चलाने के लिए, मैं कुछ इस तरह मिल , कोड पर बिताए गए समय दोनों मामलों में बराबर होना चाहिए, लेकिन ऐसा प्रतीत होता है कि स्टॉपवॉच का ओवरहेड होता है जो अपने स्वयं के समय के भीतर प्रकट होता है।

अब, अक्सर प्रोग्राम की हर पंक्ति को प्रोफाइल करने की आवश्यकता नहीं होती है, क्योंकि यह आम तौर पर विभाजित और जीत दृष्टिकोण के साथ बेहतर काम करता है। आप आमतौर पर कोड के प्रोफाइल को प्रोफाइल करके शुरू कर सकते हैं, और किसी भी प्रदर्शन समस्याओं को कम कर सकते हैं।

इसके अलावा, अधिकांश अनुप्रयोगों में, कोड की औसत रेखा परीक्षण कार्यक्रम में से बहुत धीमी होगी। इसका मतलब है कि कम स्टॉपवॉच ओवरहेड होगा।

हालांकि, स्टॉपवॉच का उपयोग करते समय अभी भी ओवरहेड है, खासकर यदि आप बहुत उपयोग करते हैं।

तो सवाल करने के लिए नीचे:

रूपरेखा के लिए stopwatches उपयोग करने के लिए सबसे प्रभावी तरीका क्या है? मैं ओवरहेड को कम कैसे कर सकता हूं? क्या यह एक कथन के चारों ओर स्टॉपवॉच को लपेटने के लिए भी लायक है?

मैं आपकी प्रतिक्रिया की सराहना करता हूं।

+6

व्यक्तिगत रूप से, मैंने खरीदे गए प्रोफाइलर्स (एएनटीएस प्रोफाइलर) हर प्रतिशत के लायक थे। मैं कभी भी "मैनुअल" प्रोफाइलिंग के बारे में कभी नहीं सोचूंगा। –

+1

पूछने के लिए खेद है, लेकिन कुछ सिस्टम का उपयोग करने की जांच क्यों नहीं करें। डायग्नोस्टिक्स कक्षाएं? मेरा मानना ​​है कि उदाहरण के लिए सीपीयू और राम उपयोग की जांच करने के लिए कक्षाएं शामिल हैं। – Eon

+1

ईकाटेक प्रोफाइलर का मुफ्त संस्करण एक वाणिज्यिक प्रोजेक्ट में इसका उपयोग करने की अनुमति देता है: http://www.eqatec.com/Profiler/LicenseTerms.aspx – ken2k

उत्तर

2

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

तथ्य यह है कि प्रोफाइलिंग आपके कार्यक्रम के समग्र चलने का समय बढ़ रही है, चिंता का विषय नहीं होना चाहिए; जैसा कि कई अन्य लोगों ने उल्लेख किया है, कार्यक्रम महत्वपूर्ण समय नहीं है, लेकिन बाधाओं को खोजने के लिए एक दूसरे के खिलाफ व्यक्तिगत भागों के चलने वाले समय की तुलना करना महत्वपूर्ण है। लेकिन एक और चिंता है। यदि कोई उपलब्ध है तो स्टॉपवॉच अंतर्निहित ओएस से उच्च आवृत्ति टाइमर का उपयोग करेगा; लेकिन यहां तक ​​कि यह काफी अधिक नहीं हो सकता है। मेरे विंडोज 7 64-बिट i5-2400 (क्वाड कोर 3.10 गीगाहर्ट्ज) पर उच्च आवृत्ति टाइमर प्रति सेकंड 3,020,556 बार टिकता है। यह बहुत पसंद है; लेकिन उस दर पर, प्रोसेसर टिकों के बीच एक हजार निर्देश निष्पादित कर सकता है। इसका मतलब है कि यदि आप एक ही निर्देश को निष्पादित करने में लगने वाले समय को मापने की कोशिश कर रहे हैं, तो आप या तो ओवरहेट के रास्ते में जा रहे हैं या रास्ते में जा रहे हैं।

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

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

1

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

हालांकि, यह कहा जा रहा है कि स्टॉपवॉच में उच्च रिज़ॉल्यूशन है, लेकिन मुझे लगता है कि आपको कोड की एक पंक्ति के रूप में छोटी चीजों को मापने में कुछ समय की त्रुटि दिखाई देगी। उदाहरण के लिए 'int n = 100' असेंबली में एक पंक्ति है, इसलिए तकनीकी शर्तों में मुझे लगता है कि यह केवल 1 टिक होगा। रनों से चलाने के लिए आप अपनी संख्या में कितनी भिन्नता देखते हैं? यदि आपको एक भिन्नता मिल रही है जो आपके औसत मूल्य का एक महत्वपूर्ण प्रतिशत है, तो वह मूल्य वास्तव में आपको वह जानकारी नहीं दे रहा है।

+0

अनुकूलन अक्षम हैं, इसलिए यह कोई समस्या नहीं होगी। मैं कभी-कभी दोनों मामलों में लगभग 1/3 औसत मूल्य की भिन्नता देखता हूं। –

+0

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

+0

ओह, और 1/3 भिन्नता के संदर्भ में, यह उस पर निर्भर करता है कि आप किस संख्या को निर्धारित करने की कोशिश कर रहे हैं, लेकिन एक भिन्नता जिसका मतलब है कि संख्या केवल परिमाण तुलना के क्रम के लिए अच्छा होने जा रही है (इसके संदर्भ में यहां अन्य उत्तर कह रहे हैं, सापेक्ष तुलना के लिए केवल अच्छा)। एक 1/3 मार्जिन त्रुटि के साथ मापने वाले 6 फीट लंबा व्यक्ति के बारे में सोचें, 'ओह, आप कहीं 4 और 8 फीट लंबा हैं।' एक बड़ा सौदा की तरह। – Sogger

4

यह देखते हुए कि Single responsibility principle द्वारा हम अक्सर सहज कार्यक्रम न केवल प्रकार के संबंध लेकिन कार्यों भी में, मैं कहूंगा कि लाइन द्वारा आवेदन लाइन की रूपरेखा का कोई किसी भी भावना नहीं है। आप प्रत्येक एकल पंक्ति "एक जिम्मेदारी" प्रोफाइलिंग में अधिक रुचि रखते हैं।

स्वाभाविक रूप से, ऐसे मामले हैं जब आप को की सूचना भी प्राप्त करने की आवश्यकता है। लेकिन इसे सभी अनुप्रयोगों में उपयोग न करें, लेकिन किसी फ़ंक्शन या एकल फ़ंक्शन के एकल भाग में इसका उपयोग न करें। इस मामले में StopWatch एक सबसे अच्छा विकल्प है। इस बात पर विचार करें कि StopWatch.NET Class है इसलिए है यह भी न्यूनतम ओवरहेड है। आपको पूर्ण पर नहीं देखना चाहिए, लेकिन पर मानों पर विचार नहीं करना चाहिए।

उम्मीद है कि इससे मदद मिलती है।

2

आपको सटीक संख्याओं को नहीं देखना चाहिए, आपको सापेक्ष मतभेदों की तलाश करनी चाहिए। ताकि आप समस्या क्षेत्रों की पहचान कर सकें। आप ऑप्टिमाइज़ करने के लिए स्थानों की तलाश कर रहे हैं जो आपकी प्रदर्शन समस्या को हल करेंगे।

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

0

शायद आपको प्रोफाइलिंग कॉल समय के संदर्भ में, और एकल लाइनों के संदर्भ में नहीं सोचना चाहिए। आखिरकार, एक विधि कॉल आमतौर पर कॉलिंग कोड में एक पंक्ति है।

public string MyMethod(string arg) 
{ 
    string result = null; 

    if (logger.IsDebugEnabled) logger.Debug("->MyMethod(" + arg + ")"); 

    // do stuff 
    result = "Hello world!"; 

    if (logger.IsDebugEnabled) logger.Debug("<-MyMethod(" + arg + ") = " + result); 

    return result; 
} 

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

2

क्या आपने CInject: http://codeinject.codeplex.com/documentation पर देखने का प्रयास किया है? यह मूल रूप से एक डीएलएल में कोड इंजेक्ट करता है। बॉक्स में से यह प्रदर्शन निगरानी प्रतीत होता है, लेकिन यह आपको इंजेक्ट करने के लिए अपना कोड बनाने देता है। आप जो करने की कोशिश कर रहे हैं उसके लिए बिल्कुल सही लगता है।

0

यदि आपके पास Visual Studio Ultimate है, तो विजुअल स्टूडियो प्रोफाइलर का उपयोग करने का प्रयास करें। यह बहुत अच्छा है।

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