2010-10-07 22 views
6

मैं जानना चाहता हूं कि for और while लॉस चक्र में हर बार लूप चक्र समाप्त होने पर स्थिति मूल्यांकन निष्पादित किया जाता है या नहीं।लूप मूल्यांकन के लिए जावा

उदाहरण:

int[] tenBig = new int[]{1,2,3,4,5,6,7,8,9,10}; 

for(int index = 0;index < tenBig.length;index++){ 
    System.out.println("Value at index: "+tenBig[index]); 
} 

index < tenBig.length हर बार लूप चक्र खत्म पर अमल किया जाएगा?

धारणा और अनुभव मुझे हाँ बताता है।

मुझे पता है कि इस उदाहरण में tenBig.length एक स्थिर है, इसलिए प्रदर्शन प्रभाव नहीं होगा।

लेकिन मान लें कि स्थिति संचालन एक अलग मामले में लंबा समय लगता है। मुझे पता है कि करने के लिए तार्किक बात यह है कि tenBig.length को एक चर के लिए असाइन करना है।

फिर भी मैं यह सुनिश्चित करना चाहता हूं कि इसका हर बार मूल्यांकन किया जाए।

+1

मुझे पता है कि यह सी ++ में मामला है। लेकिन क्या यह जावा के लिए है? – Koekiebox

+0

आपके उदाहरण में, के मध्य भाग का मूल्यांकन 11 बार किया जाएगा। एक बार जब आप 'लंबाई' की वर्तनी को ठीक कर लेते हैं तो यह वास्तव में संकलित करता है, यानी। – Powerlord

उत्तर

9

हां, यह लूप के प्रत्येक पुनरावृत्ति पर पूरे मध्य संचालन का तार्किक मूल्यांकन करेगा। जिन मामलों में जेआईटी बेहतर जानता है, ज़ाहिर है, यह चालाक चीजें कर सकता है (यहां तक ​​कि लूप स्थितियों के आधार पर लूप के अंदर सरणी सीमाओं को भी संभावित रूप से हटाया जा सकता है)।

ध्यान दें कि जेआईटी के बारे में पता नहीं है, यह विशेष रूप से इस तरह अनुकूलित करने में सक्षम नहीं हो सकता है - लेकिन ArrayList<T> के size() लाने जैसे चीजों को इनलाइन कर सकता है।

अंत में, मैं आम तौर पर पसंद करते हैं पठनीयता के लिए पाश के लिए बढ़ाया:

for (int value : tenBig) { 
    ... 
} 
बेशक

, कि आप अन्य कारणों से सूचकांक की जरूरत नहीं है यह सोचते है।

+1

लूप के लिए बढ़ाया गया एक उल्लेखनीय सुधार है: जेएलएस के मुताबिक अभिव्यक्ति (आपके मामले में 'दस बिग ') का मूल्यांकन केवल एक बार किया जाता है। –

+0

एकमात्र चीज जो मुझे "वर्धित" लूप के बारे में पसंद नहीं है वह यह है कि यह शून्य मानों की जांच नहीं करता है। दूसरे शब्दों में, यदि दस बिग ऑब्जेक्ट शून्य है, तो NullPointerException फेंक दिया जाता है, जो समझ में आता है, लेकिन अगर ऑब्जेक्ट को पहले से शून्य के लिए चेक किया गया तो यह बहुत ही अच्छा होगा। – Koekiebox

+5

@ कोएकीबॉक्स: आपको लगता है कि यह उस स्थिति में क्या करना चाहिए? इसे एक खाली संग्रह के रूप में समझें? व्यक्तिगत रूप से मुझे लगता है कि एक एनपीई सही परिणाम है। –

3

हां, लूप के अंदर रहने के लिए या कार्यक्रम निष्पादन जारी रखने के लिए अभिव्यक्ति का मूल्यांकन लूप के प्रत्येक पुनरावृत्ति के लिए किया जाना चाहिए।

याद रखें, आप इस तरह कर सकते हैं:

for(int a = 0, z = 26; a < z; a++, z--){ 
    // Do some work 
} 

उस मामले में, अभिव्यक्ति के दोनों ओर बदल जाएगा और प्रत्येक यात्रा के लिए मूल्यांकन किया जाना चाहिए।

और तुम सही हो, अगर आप पाश के लिए शर्त यह है कि एक अलग चर के लिए बाहर ले जाया जा सकता में गणना की है, आप ऐसा करना चाहिए:

for(int i = 0; i < ((someCount/2) * 21.6); i++){ 
} 

आसानी से हो सकता है:

int maxVal = (someCount/2) * 21.6; 

for(int i=0; i < maxVal; i++){ 
{ 
0

क्या आप गीलेर से पूछते हैं कि कंपाइलर दस बिग। लम्बाई मान कैश करता है क्योंकि वह जानता है कि यह लूप के दौरान नहीं बदलेगा? या आप गीलेर से पूछते हैं कि संकलक स्वचालित रूप से जानता है कि पूरे अभिव्यक्ति सूचकांक < दस बिग। लम्बाई को अगले 9 गुना के लिए मूल्यांकन करने की आवश्यकता नहीं है?

6

हां। विशेष रूप से, स्थिति भाग प्रत्येक लूप बॉडी से पहले निष्पादित किया जाता है। तो यह पूरी तरह से संभव है कि आप कभी भी लूप के शरीर में प्रवेश न करें।

तो अपने उदाहरण ले रही है:

for(int index = 0;index < tenBig.lenght;index++) { 
    /* ...body... */ 
} 

यह तार्किक (शाब्दिक नहीं) बराबर है:

int index = 0; 
while (index < tenBig.length) { // happens on each loop 
    /* ...body... */ 

    index++; 
} 
0

यह निष्पादित करने के लिए हर पाश पिछले मूल्यांकन जो होगा सहित दर्ज किया गया है, जा रहा है उपज सूचकांक < लंबाई = झूठी। इसके अलावा, दस बिग की लंबाई स्थिर होने के बावजूद, लूप हमेशा इस संपत्ति तक पहुंच जाएगा, इसलिए इसे एक चर के लिए असाइन करना आदर्श होगा (भले ही यह आपके उदाहरण में उचित गति लाभ न हो)।

1

यदि सशर्त अभिव्यक्ति लूप invariant है और आप जेआईटी मोड में चल रहे हैं, तो Loop-invariant code motion जैसे लूप ऑप्टिमाइज़ेशन किए जा सकते हैं।

लेकिन जब व्याख्या किए गए मोड में चलाया जाता है, तो अनुमान ऐसा करने के लिए बहुत अनुकूलन नहीं है।

1

यहां कई बाइटकोड compiling examples from the JVM spec हैं।

जहां तक ​​मुझे पता है, इस स्थिति का मूल्यांकन हर बार किया जाएगा।

सम्मान।

1

index < tenBig.length प्रत्येक बार लूप चक्र शुरू होने से पहले निष्पादित किया जाएगा।

public static void main(String[] args) { 
     int[] tenBig = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

     for (int index = 0; isEvaluated() && index < tenBig.length; index++) { 
      System.out.println("Value at index: " + tenBig[index]); 
     } 
    } 

    public static boolean isEvaluated() { 
     System.out.println("evaluated"); 
     return true; 
    } 

यह चक्र शुरू होने से ठीक पहले "evaluated" प्रिंट करेगा। और लूप खत्म होने से पहले एक और बार।

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