2012-09-06 11 views
8

मैं समझने की कोशिश कर रहा हूं कि प्रदर्शन समाधान से कौन से दो समाधान पसंद किए जाते हैं। उदाहरण के लिए, मैं दो कोड है:.NET मुक्केबाजी/अनबॉक्सिंग बनाम कास्टिंग प्रदर्शन

1) मुक्केबाजी/अनबॉक्सिंग

int val = 5; 
Session["key"] = val; 
int val2 = (int)Session["key"]; 

2) कास्टिंग (IntObj दुकान पूर्णांक पर पूर्णांक मूल्य संपत्ति)

IntObj val = new IntObj(5); 
Session["key"] = val; 
int val2 = ((IntObj)Session["key"]).Value; 

क्या है इन उदाहरणों के बीच स्मृति प्रबंधन अंतर? क्या ऐसे परिचालन करने का कोई तेज तरीका है?

नोट:Session सिर्फ उदाहरण के लिए है, यह किसी भी Dictionary<string, object>

+2

मैंने इसे माप नहीं लिया है, लेकिन मैं कहूंगा कि प्राइमेटिव तेज होंगे। एक वस्तु ऊपर की ओर है। लेकिन इस मामले में मुझे लगता है कि पठनीयता एक बहुत ही महत्वपूर्ण उपाय है। सीपीयू चक्र मस्तिष्क चक्रों से बहुत सस्ता हैं –

उत्तर

7

ऐसा लगता है कि आप वास्तव में यहां क्या कर रहे हैं, इनबिल्ट मुक्केबाजी के साथ मैन्युअल मुक्केबाजी की तुलना कर रहा है। इनबिल्ट मुक्केबाजी को अत्यधिक अनुकूलित किया गया है - इसलिए मुझे यहां एक बड़ा अंतर देखने की उम्मीद नहीं है, लेकिन हम जांच सकते हैं। महत्वपूर्ण रूप से, ध्यान दें कि दोनों के पास समान स्मृति प्रभाव है: एक हीप ऑब्जेक्ट जिसमें int फ़ील्ड है, प्रति int बॉक्सिंग/लपेटा गया है।

निम्नलिखित दो संपर्कों के लिए बहुत समान समय दिखाता है; मैं कहूंगा, इसलिए, बस इसे प्रत्यक्ष/अंतर्निहित तरीके से बॉक्स करें।

नोट: इसे डिबगर के बिना रिलीज़ मोड में चलाएं (आदर्श रूप से कमांड लाइन पर)। ध्यान दें कि पहली कॉल प्री-जेआईटी सब कुछ है।

using System; 
using System.Diagnostics; 
public sealed class IntObj 
{ 
    public readonly int Value; 
    public IntObj(int value) 
    { 
     Value = value; 
    } 
} 
static class Program 
{ 
    static void Main() 
    { 
     Run(1, 0, false); 
     Run(100000, 500, true); 
     Console.ReadKey(); 
    } 
    static void Run(int length, int repeat, bool report) 
    { 
     var data = new object[length]; 

     int chk = 0; 
     var watch = Stopwatch.StartNew(); 
     for (int j = 0; j < repeat; j++) 
     { 
      for (int i = 0; i < data.Length; i++) 
      { 
       data[i] = i; 
       chk += i; 
      } 
     } 
     watch.Stop(); 
     if(report) Console.WriteLine("Box: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk); 
     chk = 0; 
     watch = Stopwatch.StartNew(); 
     for (int j = 0; j < repeat; j++) 
     { 
      for (int i = 0; i < data.Length; i++) 
      { 
       chk += (int) data[i]; 
      } 
     } 
     watch.Stop(); 
     if (report) Console.WriteLine("Unbox: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk); 

     chk = 0; 
     watch = Stopwatch.StartNew(); 
     for (int j = 0; j < repeat; j++) 
     { 
      for (int i = 0; i < data.Length; i++) 
      { 
       data[i] = new IntObj(i); 
       chk += i; 
      } 
     } 
     watch.Stop(); 
     if (report) Console.WriteLine("Wrap: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk); 
     chk = 0; 
     watch = Stopwatch.StartNew(); 
     for (int j = 0; j < repeat; j++) 
     { 
      for (int i = 0; i < data.Length; i++) 
      { 
       chk += ((IntObj)data[i]).Value; 
      } 
     } 
     watch.Stop(); 
     if (report) Console.WriteLine("Unwrap: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk); 
    } 


} 
+0

धन्यवाद! अब यह देखना आसान है :) –

4

तो क्या हुआ, तेजी से होता है एक IntObj या साथ DIY बॉक्सिंग हो सकता है में निर्मित बॉक्सिंग?

मेरा अनुमान अंतर्निहित विविधता होगी। संभावना है कि दोनों कंपाइलर्स को इससे निपटने के लिए अनुकूलित किया गया है।

ऐसे परिचालन करने के लिए और अधिक "तेज़" तरीका मौजूद है?

पसंदीदा डेटा हमेशा बड़े डेटासेट के लिए इससे बचने के लिए है। छोटे सेट के लिए यह कोई फर्क नहीं पड़ता।

+0

मैंने उदाहरण के लिए एक सत्र दिया है, यह एक साधारण शब्दकोश <स्ट्रिंग, ऑब्जेक्ट>/ –

+0

हो सकता है, मुझे लगता है कि सवाल IntObj के बारे में था। कंटेनर (सत्र) बहुत प्रासंगिक नहीं है। –

0

मैं सी # डाली ऑपरेटर द्वारा उत्पन्न आईएल निर्देश के विभिन्न प्रकार में वर्गीकृत:

मुक्केबाजी (बॉक्स आईएल अनुदेश) और unboxing (Unbox आईएल अनुदेश) inhertiance पदानुक्रम (सी ++ में dynamic_cast तरह के माध्यम से कास्टिंग, आईएल अनुदेश castclass का उपयोग करता है सत्यापित करने के लिए) आदिम प्रकारों के बीच कास्टिंग (जैसे सी ++ में static_cast, आदिम प्रकारों के बीच विभिन्न प्रकार के कास्टों के लिए आईएल निर्देशों के बहुत सारे हैं) उपयोगकर्ता परिभाषित रूपांतरण ऑपरेटरों को कॉल करना (आईएल स्तर पर वे केवल उपयुक्त op_XXX विधि पर विधि कॉल करते हैं)।

अंतर यह है कि कास्टिंग अतिरिक्त मेमोरी आवंटित करता है क्योंकि एक नया संदर्भ प्रकार बनाया जाता है।

+3

तो यह सवाल का जवाब कैसे देता है? (बॉक्सिंग भी ढेर पर एक नया उदाहरण बनाता है) –

2

कुछ करने का सबसे तेज़ तरीका यह बिल्कुल नहीं है। एक ही समय में अधिक प्रकार की सुरक्षा, पठनीयता और संभावित प्रदर्शन प्राप्त करने के लिए मुक्केबाजी की बड़ी मात्रा से बचने के लिए अपने डेटा को पुन: स्थापित करने का प्रयास करें।

मुझे यह असंभव लगता है कि आपको असीमित शब्दकोश में बड़ी संख्या में असंबंधित पूर्णांक (या अन्य मूल्य प्रकार) तत्वों को स्टोर करने की आवश्यकता है। आम तौर पर मूल्य कुछ वस्तुओं में व्यवस्थित होते हैं जो एक साथ ताल बनाते हैं, इस मामले में आप अनियमित शब्दकोश में शीर्ष स्तर की वस्तु को स्टोर करते हैं और केवल एक कलाकार की आवश्यकता होती है। गहरे तत्वों के लिए आप दृढ़ता से टाइप किए गए वर्गों (जैसे Dictionary<string,int>) का उपयोग करेंगे, जहां कोई समस्या नहीं होने के कारण से ही यह समस्या हल हो जाती है।

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

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