2013-07-17 7 views
10

मैंने आज सी # और जावा में post about performance improvement पढ़ा।स्थानीय चर या कक्षा फ़ील्ड?

मैं अब भी इस पर अटक:


19. नहीं अति प्रयोग उदाहरण चर क्या

प्रदर्शन स्थानीय चर का उपयोग करके सुधार किया जा सकता।

public void loop() { 
    int j = 0; 
    for (int i = 0; i<250000;i++){ 
    j = j + 1; 
    } 
} 

उदाहरण 2:: उदाहरण 1 में कोड उदाहरण में कोड 2.

example1 तुलना में तेजी से निष्पादित करेंगे

int i; 
public void loop() { 
    int j = 0; 
    for (i = 0; i<250000;i++){ 
    j = j + 1; 
    } 
} 

दरअसल, मैं क्यों समझ में नहीं आता यह होना चाहिए कुछ मेमोरी को तुरंत चालू करने के लिए तेज़ रहें और loop पर कॉल करने पर हर बार इसे रिलीज़ करें जब मैं किसी फ़ील्ड में सरल पहुंच कर सकता हूं।

यह शुद्ध जिज्ञासा है, मैं कक्षा 'स्कोप' में चर 'i' डालने की कोशिश नहीं कर रहा हूं: पी क्या यह सच है कि स्थानीय चर का उपयोग करने के लिए तेज़ है? या शायद कुछ मामलों में?

+1

मुझे लगता है कि प्रदर्शन अंतर नगण्य होगा , आपको कोड को समझने में डेवलपर प्रदर्शन के बारे में अधिक चिंतित होना चाहिए। यदि आपके पास कोई क्षेत्र या संपत्ति है जो स्थानीय चर होना चाहिए, तो मैं इसके उद्देश्य को समझने में विवादित होगा। यदि आप प्रदर्शन अंतर को जानना चाहते हैं, तो इसे बेंचमार्क क्यों न करें (या आईएल को दोनों उत्पन्न करें)? – Matthew

+3

ढेर से चर का उपयोग करना एक ढेर संदर्भ के माध्यम से इसे एक्सेस करने से शायद तेज़ है। –

+2

उस लेख में इतनी बुरी सलाह मुझे नहीं पता कि –

उत्तर

9
  1. तेजी से ढेर ढेर।

    void f() 
    { 
        int x = 123; // <- located in stack 
    } 
    
    int x; // <- located in heap 
    void f() 
    { 
        x = 123 
    } 
    
  2. the principle of locality data मत भूलना। सीपीयू कैश में स्थानीय डेटा बेहतर कैश किया जाना चाहिए। यदि डेटा बंद है, तो वे पूरी तरह से सीपीयू कैश में लोड हो जाएंगे, और सीपीयू को उन्हें स्मृति से नहीं लेना होगा।

+0

मुझे लगता है कि आप बहुत अधिक सरल बना रहे हैं। स्थानीय चर वास्तव में ढेर पर स्थित हो सकता है और एक क्षेत्र ढेर पर स्थित हो सकता है। – svick

+0

यदि आपके पास सीधा पता है तो स्टैक या ढेर में कोई फर्क नहीं पड़ता है। – Andrey

+0

मैं सहमत हूं, यदि आप फ़ील्ड के साथ वस्तु और संरचना पर संदर्भ का मतलब है – oakio

1

मुझे संदेह है कि बहुत कम अंतर है, हालांकि मामले में जहां चर वस्तु का सदस्य है, प्रत्येक एक्सेस को this (प्रभावी रूप से) के माध्यम से एक संकेत की आवश्यकता होती है, जबकि स्थानीय चर नहीं होता है।

अधिक आम तौर पर, ऑब्जेक्ट को सदस्य i के लिए कोई आवश्यकता नहीं है, इसका उपयोग केवल लूप के संदर्भ में किया जाता है, इसलिए इसे किसी भी मामले में स्थानीय उपयोग करने के लिए स्थानीय बनाना बेहतर होता है।

5

प्रदर्शन चर को प्राप्त करने के लिए आवश्यक चरणों की संख्या के नीचे है। लोकल वेरिएबल पतों को कंपाइल टाइम (वे स्टैक पर ज्ञात ऑफ़सेट हैं) पर ज्ञात हैं, किसी सदस्य को एक्सेस करने के लिए, जब आप सदस्य ऑब्जेक्ट का पता प्राप्त कर सकते हैं, तो वास्तविक ऑब्जेक्ट का पता प्राप्त करने के लिए ऑब्जेक्ट 'यह' लोड करें।

3

भले ही यह होगा, इस मामले में लगभग गैर-मापनीय अंतर होगा। Probabbly पहले मामले में, वहाँ कुछ अनुकूलन प्रोसेसर रजिस्ट्री स्तर पर किया जाता है, लेकिन फिर से है:

  • यह लगभग अप्रासंगिक है
  • और क्या अधिक महत्वपूर्ण अक्सर अप्रत्याशित है।

स्मृति के मामले में, यह बिल्कुल समान है, इसमें कोई अंतर नहीं है।

पहला मामला यह आम तौर पर बेहतर: के रूप में आप की घोषणा चर रहे थे यह तुरंत, प्रयोग किया जाता है जो आमतौर पर अच्छा पैटर्न प्रयोग किया जाता है, यह (जिम्मेदारियों का स्कोप)

  • आसान refactor
  • को समझने के लिए

    • आसान है के रूप में
    +0

    दूसरा उदाहरण अधिक स्मृति का उपयोग करता है जब विधि निष्पादन में नहीं होती है, क्योंकि यह चर क्लास के प्रत्येक उदाहरण के लिए स्मृति में हमेशा होता है, भले ही 'लूप' विधि को कॉल किया जाए या नहीं। – Matthew

    +0

    @ मैथ्यू: विधि में घोषित सभी स्थानीय चर (वास्तव में वर्तमान निष्पादन के दौरान या नहीं) आवंटित किए जाते हैं और रास्ते से * स्टैक * पर धक्का दिए जाते हैं। – Tigran

    +0

    हां, हालांकि 'लूप' विधि निकलने पर स्मृति को मुक्त किया जाता है, लेकिन उदाहरण के मामले में नहीं 2. – Matthew

    0

    मैंने 500,000 पुनरावृत्तियों के साथ एक गणना का परीक्षण किया जहां मैंने स्थानीय रूप से लगभग 20 चर का उपयोग किया और यह फ़ील्ड के साथ करता है। स्थानीय चर परीक्षण लगभग 20 मिलीसेकंड था और फ़ील्ड वाले एक के बारे में 30 मिलीसेकंड था। जब आप स्थानीय चर का उपयोग करते हैं तो एक महत्वपूर्ण प्रदर्शन लाभ होता है।

    चाहे प्रदर्शन अंतर प्रासंगिक है, परियोजना पर निर्भर करता है। आपके औसत व्यावसायिक अनुप्रयोग में प्रदर्शन लाभ ध्यान देने योग्य नहीं हो सकता है और पठनीय/रखरखाव योग्य कोड के लिए जाना बेहतर है, लेकिन मैं ध्वनि संश्लेषण सॉफ्टवेयर पर काम कर रहा हूं, जहां नैनो-अनुकूलन वास्तव में प्रासंगिक हो जाते हैं।

    0

    सी # में एक और मामूली अंतर उत्पन्न एमएसआईएल निर्देशों की संख्या है (मुझे लगता है कि यह जावा में समान है)।

    यह एक उदाहरण क्षेत्र लोड करने के लिए दो निर्देश लेता है:

    ldarg.0     // load "this" reference onto stack 
    ldfld MyClass.myField // find the field and load its value 
    

    ... लेकिन यह केवल एक स्थानीय चर लोड करने के लिए एक शिक्षा लेता है:

    ldloc.0     // load the value at index 0 from the list of local variables 
    
    संबंधित मुद्दे