2010-10-28 15 views
17

निम्नलिखित 2 परिदृश्यों पर विचार करें:लूपिंग के दौरान कौन सा खर्च होता है; असाइनमेंट या एक कथन?

boolean b = false; 
int i = 0; 
while(i++ < 5) { 
    b = true; 
} 

या

boolean b = false; 
int i = 0; 
while(i++ < 5) { 
    if(!b) { 
     b = true; 
    } 
} 

कौन सा "महंगा" करना है? अगर उत्तर प्रयुक्त भाषा/कंपाइलर पर निर्भर करता है, तो कृपया प्रदान करें। मेरी मुख्य प्रोग्रामिंग भाषा जावा है।

कृपया प्रश्न पूछें कि मैं ऐसा क्यों करना चाहूंगा .. वे केवल बेयरबोन उदाहरण हैं जो प्रासंगिक इंगित करते हैं: क्या एक चर को एक लूप में एक ही मान को बार-बार सेट करना चाहिए या इसे होना चाहिए प्रत्येक लूप पर परीक्षण किया गया है कि इसमें बदलने के लिए आवश्यक मूल्य है?

+2

संभावित डुप्लिकेट [क्या तेज़ तब गुणा और असाइनमेंट है?] (Http://stackoverflow.com/questions/4024201/are-if-thens-faster-then-multiplication-and-assignment) –

+0

अगर मुझे याद है मेरा कंपाइलर क्लास सही ढंग से, http://en.wikipedia.org/wiki/Branch_predictor के कारण ये दोनों ही इसके बारे में होंगे। मुझे लगता है कि पहली बार शाखा करने के लिए थोड़ा और समय लगेगा लेकिन उसके बाद संकलक पूर्वानुमान कर सकता है और तदनुसार समायोजित कर सकता है। –

+0

यहां आपको कई जवाब मिलेंगे http://www.agner.org/optimize/optimizing_cpp.pdf – ruslik

उत्तर

1

क्या आप यह पता लगाने की कोशिश कर रहे हैं कि असाइनमेंट करने पर प्रत्येक लूप प्रत्येक लूप को चेक करने और केवल परीक्षण स्थिति की संतुष्टि पर एक बार असाइन करने के बजाय कुल रन टाइम में तेज़ है?

उपर्युक्त उदाहरण में मुझे लगता है कि पहला तेज है। आप 5 असाइनमेंट करते हैं। बाद में आप 5 टेस्ट और फिर एक असाइनमेंट करते हैं।

लेकिन आपको निश्चित रूप से जानने के लिए पुनरावृत्ति गिनती और कुछ स्टॉपवॉच टाइमर में फेंकने की आवश्यकता होगी।

0

किसी भी संकलक (सिवाय, शायद, डिबग में)

bool b = true; 

करने के लिए इन दोनों बयानों को अनुकूलित करेंगे लेकिन आम तौर पर, काम और शाखा के सापेक्ष गति संकलक पर प्रोसेसर आर्किटेक्चर पर निर्भर करते हैं, और नहीं। एक आधुनिक, सुपर-स्केलर प्रोसेसर शाखाओं पर भयंकर प्रदर्शन करता है। एक साधारण सूक्ष्म नियंत्रक किसी भी निर्देश के अनुसार लगभग उसी चक्र का उपयोग करता है।

0

अपने barebones उदाहरण (और शायद अपने वास्तविक आवेदन) के सापेक्ष:

boolean b = false; 
// .. other stuff, might change b 
int i = 0; 
// .. other stuff, might change i 
b |= i < 5; 
while(i++ < 5) { 
    // .. stuff with i, possibly stuff with b, but no assignment to b 
} 

समस्या हल हो?

लेकिन वास्तव में - यह आपके परीक्षण की लागत (आमतौर पर केवल if (boolean) से अधिक) और आपके असाइनमेंट की लागत (आमतौर पर केवल primitive = x से अधिक) का सवाल होने जा रहा है। यदि परीक्षण/असाइनमेंट महंगा है या आपका लूप काफी लंबा है या आपके पास पर्याप्त प्रदर्शन मांगें हैं, तो आप इसे दो हिस्सों में तोड़ना चाहेंगे - लेकिन उन सभी मानदंडों की आवश्यकता है कि आप परीक्षण करें कि चीजें कैसे कार्य करती हैं। बेशक, यदि आपकी आवश्यकताएं अधिक मांग कर रही हैं (कहें, b आगे और पीछे फ्लिप कर सकते हैं), तो आपको अधिक जटिल समाधान की आवश्यकता हो सकती है।

3

क्या आपने इसका परीक्षण किया है? लिनक्स सिस्टम पर काम करते हुए, मैंने आपके पहले उदाहरण को LoopTestNoIf.java नामक फ़ाइल में रखा है और आपका दूसरा LoopTestWithIf.java नामक फ़ाइल में रखा गया है, जिसमें से प्रत्येक के चारों ओर एक मुख्य फ़ंक्शन और क्लास लपेटा गया है, संकलित किया गया है, और फिर इस बैश स्क्रिप्ट के साथ भाग गया:

#!/bin/bash 
function run_test { 
    iter=0 
    while [ $iter -lt 100 ] 
    do 
    java $1 
    let iter=iter+1 
    done 
} 
time run_test LoopTestNoIf 
time run_test LoopTestWithIf 

परिणाम थे:

real 0m10.358s 
user 0m4.349s 
sys  0m1.159s 

real 0m10.339s 
user 0m4.299s 
sys  0m1.178s 

दिखा कि अगर होने बनाता है अपने सिस्टम पर यह मामूली तेजी।

+0

मुझे इसी तरह के परिणाम मिलते हैं, कृपया एंडी लेस्टर को मेरी टिप्पणी देखें। – heikkim

27

कृपया rules of Optimization Club को न भूलें।

  1. अनुकूलन क्लब का पहला नियम है, आप अनुकूलित नहीं करते हैं।
  2. ऑप्टिमाइज़ेशन क्लब का दूसरा नियम है, आप मापने के बिना अनुकूलित नहीं करते हैं।
  3. यदि आपका ऐप अंतर्निहित परिवहन प्रोटोकॉल से तेज़ी से चल रहा है, तो ऑप्टिमाइज़ेशन समाप्त हो गया है।
  4. एक समय में एक कारक।
  5. कोई मार्केटरोइड नहीं, कोई मार्केट्रॉइड शेड्यूल नहीं।
  6. परीक्षण तब तक जारी रहेगा जब तक इसे करना होगा।
  7. यदि यह ऑप्टिमाइज़ेशन क्लब में आपकी पहली रात है, तो आपको एक टेस्ट केस लिखना होगा।

ऐसा लगता है कि आपने नियम तोड़ दिया है 2. आपके पास कोई माप नहीं है। यदि आप वास्तव में जानना चाहते हैं, तो आप परिदृश्य बी के खिलाफ परिदृश्य ए चलाते हुए एक परीक्षण स्थापित करके स्वयं को प्रश्न का उत्तर देंगे और उत्तर पाता है। विभिन्न वातावरण के बीच बहुत अंतर हैं, हम जवाब नहीं दे सकते हैं।

+0

मैं अनुकूलित नहीं कर रहा था। मेरा प्रेरक जिज्ञासा था। मैं आपका उत्तर स्वीकार करता हूं: "विभिन्न वातावरण के बीच बहुत अंतर हैं, हम जवाब नहीं दे सकते।" – heikkim

+0

मैंने 100 000 बार लूप करके जावा पर इसका परीक्षण किया और ऐसा लगता है कि परीक्षण एकदम सही है जब परीक्षण काफी सरल होता है। – heikkim