2010-05-19 15 views
22

मैंने अपनी परियोजनाओं को .NET 4.0 (VS2010 के साथ) में अपग्रेड करने के बाद मुझे एहसास हुआ कि वे .NET 2.0 (VS2008) में धीमे गति से चलते हैं। तो मैं बेंचमार्क के लिए विभिन्न लक्ष्य फ़्रेमवर्क के साथ दोनों VS2008 & VS2010 में एक साधारण सांत्वना आवेदन का निर्णय लिया:.NET 4.0 रनटाइम .NET 2.0 रनटाइम से धीमे हैं?

  • VS2008
    • लक्ष्य फ्रेमवर्क 2.0: ~ 0.25 सेकंड

      using System; 
      using System.Diagnostics; 
      using System.Reflection; 
      
      namespace RuntimePerfTest 
      { 
          class Program 
          { 
           static void Main(string[] args) 
           { 
            Console.WriteLine(Assembly.GetCallingAssembly().ImageRuntimeVersion); 
            Stopwatch sw = new Stopwatch(); 
      
            while (true) 
            { 
             sw.Reset(); 
             sw.Start(); 
      
             for (int i = 0; i < 1000000000; i++) 
             { 
      
             } 
      
             TimeSpan elapsed = sw.Elapsed; 
             Console.WriteLine(elapsed); 
            } 
           } 
          } 
      } 
      

      यहाँ परिणाम है

    • लक्ष्य फ्रेमवर्क 3.0: ~ 0.25 सेकंड
    • लक्ष्य फ्रेमवर्क 3.5: ~ 0.25 सेकंड
  • VS2010
    • लक्ष्य फ्रेमवर्क 2.0: ~ 3.8 सेकंड
    • लक्ष्य फ्रेमवर्क 3.0: ~ 3.8 सेकंड
    • लक्ष्य फ्रेमवर्क 3.5: ~ 1.51 सेकंड
    • लक्ष्य फ्रेमवर्क 3.5 ग्राहकों का प्रोफाइल: ~ 3.8 सेकंड
    • लक्ष्य फ्रेमवर्क 4.0: ~ 1.01 सेकंड
    • लक्ष्य फ्रेमवर्क 4.0 ग्राहक प्रोफ़ाइल: ~ 1.01 सेकंड

मेरे प्रारंभिक निष्कर्ष जाहिर है कि VS2008 तेजी VS2010 के साथ संकलित प्रोग्राम्स से काम कर के साथ संकलित प्रोग्राम्स।

क्या कोई भी VS2008 और VS2010 के बीच उन प्रदर्शन परिवर्तनों को समझा सकता है? और VS2010 के अंदर अलग-अलग लक्ष्य ढांचे के बीच?

+6

क्या आप इन्हें विजुअल स्टूडियो में डिबगर के माध्यम से चला रहे हैं या रिलीज मोड में ऐप्स चला रहे हैं? –

+2

क्या आपने बाह्य प्रभाव को कम करने के लिए कई रनों का परीक्षण किया था? जैसा कि यह खड़ा है, परिणाम अकेले मौके के कारण हो सकते हैं। भले ही यह * दिखता है * निर्णायक, एक भी रन इस परीक्षण में लगभग * नहीं * महत्व प्रदान करेगा। –

+0

क्या आपने इसे वीएस के बाहर चलाने की कोशिश की है? – eflles

उत्तर

27

मुझे लगता है कि मुझे यह मिल गया है।

यदि आप 64 बिट मशीन पर चल रहे हैं, तो सुनिश्चित करें कि बिल्ड "x86" के बजाय "कोई भी CPU" पर सेट है। ऐसा करने से मेरी मशीन पर समस्या ठीक हो गई।

वीएस -2010 में "किसी भी सीपीयू" से "x86" तक नई परियोजनाओं के लिए डिफ़ॉल्ट बदल गया - मुझे विश्वास है कि यह 64 बिट मशीनों पर डिफ़ॉल्ट रूप से संपादन और जारी रखना था (क्योंकि यह केवल x86 का समर्थन करता है)।

64 बिट मशीन पर x86 प्रक्रिया चलाना स्पष्ट रूप से कुछ हद तक उपनिवेश है।

संपादित करें: डस्टिन की टिप्पणियों के अनुसार, x64 के बजाए x86 चलाने से स्मृति के अधिक कुशल उपयोग (छोटे संदर्भ) के संदर्भ में प्रदर्शन लाभ हो सकते हैं।

मैं भी ईमेल द्वारा इस बारे में डस्टिन साथ पत्राचार किया, और वह इन कारणों में शामिल हैं:

Fwiw, डिफ़ॉल्ट लक्ष्य मंच ENC समर्थन करने के लिए नहीं बदला गया था। हमारे पास पहले से ही 2 रिलीज़ के लिए x64 पर टूटा हुआ ईएनसी भेज दिया गया था। तो स्वयं ही, ईएनसी वास्तव में स्विच करने के लिए एक अनिवार्य कारण नहीं था। प्राथमिक कारण हम बंद (कोई विशेष क्रम में) थे:

  • IntelliTrace 64 पर समर्थित नहीं है। तो, सबसे अच्छे नए सुविधाओं में से एक x12 विंडोज पर किसी भी CPU प्रोजेक्ट्स पर काम नहीं करेगा।

  • x64 EXE x86 EXEs की तुलना में x64 विंडोज़ पर धीमी गति से चलते हैं। तो, x86 डीबग का विचार, x64 रिलीज का मतलब होगा कि रिलीज में "अनुकूलित" बनाता है वास्तव में खराब प्रदर्शन करेगा।

  • ग्राहक को शिकायत करते समय ग्राहक शिकायतें और यह पता लगाना कि काम नहीं करता है, भले ही यह पर उनकी मशीन पर काम करता है। ये अक्सर पी/Invoke के आसपास थे, लेकिन वहां कई अन्य धारणाएं हैं जिन्हें एप्लिकेशन में बनाया जा सकता है जो को अलग-अलग गठबंधन के साथ चलाते समय तोड़ सकता है।

ऊपर तथ्य यह है कि एक किसी भी सीपीयू कोई लाभ लाता है के साथ मिलकर कारणों (यानी आप वास्तव में विस्तार का पता अंतरिक्ष के लाभ लेने नहीं कर सकता क्योंकि EXE अभी भी 86 पर चल सकते हैं) था कारण यह है कि डिफ़ॉल्ट स्विच किया गया था।

रिक बेयर्स के पास इस विषय पर उत्कृष्ट पोस्ट here है।

+1

क्या अंतर प्लेटफार्म लक्ष्य हो सकता है? csc.exe डिफ़ॉल्ट रूप से AnyCPU का उपयोग करता है, जबकि वीएस 2010 ने डिफ़ॉल्ट को x86 में बदल दिया है। –

+0

@ 0xA3: क्या मूल रूप से मेरा जवाब क्या नहीं कहता है? –

+4

हां, यह है, लेकिन आपका जवाब यह नहीं कहता कि अभी तक जब मैंने अपनी टिप्पणी लिखी है ;-) मैं चाहता हूं कि कोई जवाब तुरंत रीफ्रेश करें यदि कोई अपना उत्तर अपडेट करता है। –

8

मुझे विश्वास है कि आपका बेंचमार्क त्रुटिपूर्ण है। आपके नमूना कार्यक्रम के लिए वीएस 2008 और वीएस 2010 से आईएल कोड रिलीज मोड में समान है (वीएस 2008 लक्ष्यीकरण .NET 2.0 और वीएस 2010 लक्ष्यीकरण डिफ़ॉल्ट सेटिंग्स के साथ .NET 4.0)।

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  69 (0x45) 
    .maxstack 2 
    .locals init ([0] class [System]System.Diagnostics.Stopwatch sw, 
      [1] int32 i, 
      [2] valuetype [mscorlib]System.TimeSpan elapsed) 
    IL_0000: call  class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetCallingAssembly() 
    IL_0005: callvirt instance string [mscorlib]System.Reflection.Assembly::get_ImageRuntimeVersion() 
    IL_000a: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_000f: newobj  instance void [System]System.Diagnostics.Stopwatch::.ctor() 
    IL_0014: stloc.0 
    IL_0015: ldloc.0 
    IL_0016: callvirt instance void [System]System.Diagnostics.Stopwatch::Reset() 
    IL_001b: ldloc.0 
    IL_001c: callvirt instance void [System]System.Diagnostics.Stopwatch::Start() 
    IL_0021: ldc.i4.0 
    IL_0022: stloc.1 
    IL_0023: br.s  IL_0029 
    IL_0025: ldloc.1 
    IL_0026: ldc.i4.1 
    IL_0027: add 
    IL_0028: stloc.1 
    IL_0029: ldloc.1 
    IL_002a: ldc.i4  0x3b9aca00 
    IL_002f: blt.s  IL_0025 
    IL_0031: ldloc.0 
    IL_0032: callvirt instance valuetype [mscorlib]System.TimeSpan [System]System.Diagnostics.Stopwatch::get_Elapsed() 
    IL_0037: stloc.2 
    IL_0038: ldloc.2 
    IL_0039: box  [mscorlib]System.TimeSpan 
    IL_003e: call  void [mscorlib]System.Console::WriteLine(object) 
    IL_0043: br.s  IL_0015 
} // end of method Program::Main 

एक बात है कि विभिन्न मंच लक्ष्य है हो सकता है: इसलिए आप समय वी.एस. 2008 और वी.एस. 2010 के बीच दोनों compilers निम्नलिखित कोड का उत्सर्जन में एक फर्क नज़र नहीं आएगा। वीएस 2010 डिफ़ॉल्ट प्लेटफॉर्म लक्ष्य के रूप में x86 का उपयोग करता है जबकि वीएस 2008 AnyCPU का उपयोग करता है। यदि आप 64-बिट सिस्टम पर हैं तो इसके परिणामस्वरूप वीएस 2008 बनाम वीएस 2010 के निर्माण के लिए विभिन्न जेआईटी कंपाइलर्स का उपयोग किया जाएगा। इससे अलग-अलग परिणाम हो सकते हैं क्योंकि जेआईटी कंपाइलर्स अलग से विकसित किए जाते हैं।

5

मैं मानता हूं कि बेंचमार्क एक दोषपूर्ण है।

  • यह बहुत छोटा है।
  • जैसा कि पहले बताया गया था, x86/x64 के लिए अलग-अलग जेआईटी लूप को अलग-अलग अनुकूलित कर रहे हैं।
  • यह वास्तव में केवल स्टैक वैरिएबल का परीक्षण करता है जो संभवतया तेज़ी से पहुंच के लिए जेटिट किए जाते हैं। एक और वास्तविक दुनिया बेंचमार्क कम से कम पता स्थान तक पहुंच जाना चाहिए।

अधिकांश अतिरिक्त समय x86 मामलों में वाह परत द्वारा लिया जाता है। हालांकि, एक x64 प्रक्रिया की अंतर्निहित अक्षमता लंबे समय तक वाह बेंचमार्क के ऊपरी हिस्से से अधिक हो जाएगी जो वास्तव में स्मृति को छूती है। वास्तव में, अगर बेंचमार्क स्मृति तक पहुंचने के लिए थे (ढेर पर वस्तुओं को बनाकर और एक्सेस करके), तो आप वाह परत सूचक सूचक लाभ प्राप्त करेंगे।

0

हमें एक ही समस्या है। .NET 3.5 (VS2008) से .NET 4 (VS2010) तक wpf प्रोजेक्ट को कनवर्ट करने के बाद, GUI बहुत कम उत्तरदायी है (प्रत्येक क्लिक के लिए लगभग 1 सेकंड देरी)।

कुछ जांच के बाद, हमने पाया, ऐसा इसलिए है क्योंकि विजुअल स्टूडियो 2010 अधिक संसाधनों को बेकार करता है और जब हम VS2010 से degub करते हैं तो सब कुछ धीमा होता है। जब हम निर्मित प्रोजेक्ट को .exe के रूप में चलाते हैं तो यह तेज़ी से चलता है।