क्यों मुद्रण "#" की तुलना में "बी" नाटकीय रूप से धीमा है?


2745

मैंने 1000x के दो मैट्रिक्स बनाए 1000:

पहला मैट्रिक्स: Oऔर #
दूसरी मैट्रिक्स: Oऔर B

निम्नलिखित कोड का उपयोग करते हुए, पहले मैट्रिक्स को पूरा करने में 8.52 सेकंड लगे:

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("#");
        }
    }

   System.out.println("");
 }

इस कोड के साथ, दूसरे मैट्रिक्स को पूरा करने में 259.152 सेकंड लगे:

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("B"); //only line changed
        }
    }

    System.out.println("");
}

नाटकीय रूप से अलग-अलग समय के पीछे क्या कारण है?


जैसा कि टिप्पणियों में सुझाया गया है, मुद्रण में केवल कुछ सेकंड System.out.print("#");लगते हैं 7.8871, जबकि System.out.print("B");देता है still printing...

जैसा कि अन्य लोगों ने बताया कि यह उनके लिए सामान्य रूप से काम करता है, मैंने उदाहरण के लिए Ideone.com की कोशिश की , और कोड के दोनों टुकड़े एक ही गति से निष्पादित होते हैं।

परीक्षण की स्थितियाँ:

  • मैंने नेटबेंस 7.2 से इस परीक्षण को चलाया , आउटपुट इसके कंसोल में
  • मैंने System.nanoTime()माप के लिए इस्तेमाल किया

62
यादृच्छिक जनरेटर के प्रभाव को खत्म करने के लिए rand.nextInt (4) == 0 से i <250 बदलने की कोशिश करें। आप उस
अनचाहे

3
दोनों मेरी मशीन पर समान समय के लिए चलते हैं, ~ 4 सेकंड।
सोतीरियो डेलिमनोलिस

155
यदि आप यह सुझाव दे रहे हैं कि मुद्रण B को मुद्रण से अधिक समय लगता है # .... तो आप यादृच्छिक चर r पर निर्भर होने के बजाय सभी B & सभी # को मुद्रित करने का प्रयास क्यों नहीं करते हैं
Kakarot

18
स्वीकृत उत्तर के आधार पर, आपने स्पष्ट रूप से इसे किसी फ़ाइल या / dev / null पर पुनर्निर्देशित आउटपुट के साथ चलाने का प्रयास नहीं किया।
बरमेर

24
@ फ़ेज, रैंडम () क्रिप्टोग्राफ़िक नहीं है और इसलिए एन्ट्रापी पूल का उपयोग नहीं करता है।
विभाजित करें

जवाबों:


4070

शुद्ध अटकलें यह है कि आप एक ऐसे टर्मिनल का उपयोग कर रहे हैं , जो वर्ण-रैपिंग के बजाय शब्द-रैपिंग करने का प्रयास करता है, और Bएक शब्द चरित्र के #रूप में, लेकिन एक गैर-शब्द चरित्र के रूप में व्यवहार करता है । इसलिए जब यह एक पंक्ति के अंत तक पहुंचता है और लाइन को तोड़ने के लिए जगह की तलाश करता है, तो यह #लगभग तुरंत देखता है और खुशी से वहां टूट जाता है; जबकि इसके साथ B, इसे लंबे समय तक खोजते रहना पड़ता है, और इसमें लपेटने के लिए अधिक पाठ हो सकता है (जो कुछ टर्मिनलों पर महंगा हो सकता है, उदाहरण के लिए, बैकस्पेस को आउटपुट करना, फिर लिपटा जा रहा अक्षरों को अधिलेखित करने के लिए रिक्त स्थान को आउटपुट करना)।

लेकिन यह शुद्ध अटकलें हैं।


559
यह वास्तव में सही उत्तर है! Bइसे हल करने के बाद एक स्थान जोड़ना ।
कुबा स्पैनी

261
कुछ जवाब हैं जो कठिन सीखा अनुभव से आते हैं। TJ और I (चूंकि हम दोस्त हैं) Apple के दिनों में बड़े हुए हैं] [और zx80 / ​​81। तब शब्द लपेट में कोई निर्माण नहीं किया गया था। इसलिए हम दोनों ने अपना लेखन समाप्त कर दिया - एक से अधिक बार। और वे सबक आपके साथ रहते हैं, वे आपके छिपकली के मस्तिष्क में जल जाते हैं। लेकिन अगर आप उसके बाद कोड करने के लिए झुके हैं, जब आपका पर्यावरण शब्द सब कुछ लपेटता है, या आप इसे मैन्युअल रूप से रनटाइम से पहले करते हैं, तो वर्ड रैप के साथ मुद्दों में भागना कठिन है।
जॉकएम

315
शानदार कटौती। लेकिन हमें इस पाठ से सामान्यीकरण करना चाहिए, और हमेशा आउटपुट को समाप्त करने के साथ प्रदर्शन को मापना चाहिए, जिसे / dev / null (Windows पर NUL) या कम से कम एक फ़ाइल में निर्देशित किया जाना चाहिए। किसी भी प्रकार के कंसोल पर प्रदर्शित करना आम तौर पर बहुत महंगा है, और हमेशा समय बिगाड़ता है - भले ही नाटकीय रूप से इस पर भ्रमित न हो।
बॉब कर्न्स

37
@ मित्र: वर्डवैपिंग System.out.printlnनहीं करता है; यह जिस चीज़ को आउटपुट कर रहा था वह वर्ड-रैपिंग कर रहा था (और ब्लॉक System.out.printlnकरना था , इसलिए इंतजार करना पड़ा)।
टीजे क्राउडर

35
@ क्रिस - वास्तव में, मैं तर्क दूंगा कि इन्हें प्रिंट नहीं किया जा रहा है, एल्गोरिथ्म के सटीक समय प्राप्त करने की समस्या के लिए। हर बार जब आप किसी कंसोल (किसी भी प्रकार का) पर प्रिंट करते हैं, तो आप बाहरी प्रसंस्करण के सभी तरीकों का आह्वान कर रहे हैं जो आपके प्रदर्शन के परीक्षण से संबंधित नहीं है। यह आपकी माप प्रक्रिया, शुद्ध और सरल में एक बग है। दूसरी ओर, यदि आप समस्या को माप के रूप में नहीं देखते हैं, लेकिन विसंगति को समझते हैं, तो हाँ, नहीं मुद्रण एक डिबगिंग चाल है। यह नीचे आता है, आप किस समस्या को हल करने की कोशिश कर रहे हैं?
बॉब कर्न्स

209

मैंने ग्रहण बनाम नेटबीन्स 8.0.2 पर परीक्षण किया, जावा संस्करण 1.8 दोनों के साथ; मैंने System.nanoTime()माप के लिए इस्तेमाल किया ।

ग्रहण:

मुझे दोनों मामलों पर एक ही समय मिला - लगभग 1.564 सेकंड

NetBeans:

  • "#" का उपयोग करना: 1.536 सेकंड
  • "बी" का उपयोग करना: 44.164 सेकंड

तो, ऐसा लग रहा है कि नेटबैंस का कंसोल पर कंसोल पर खराब प्रदर्शन है।

अधिक शोध के बाद मैंने महसूस किया कि समस्या नेटबीन्स के अधिकतम बफ़र की लाइन-रैपिंग है (यह System.out.printlnकमांड के लिए प्रतिबंधित नहीं है ), इस कोड के साथ प्रदर्शित:

for (int i = 0; i < 1000; i++) {
    long t1 = System.nanoTime();
    System.out.print("BBB......BBB"); \\<-contain 1000 "B"
    long t2 = System.nanoTime();
    System.out.println(t2-t1);
    System.out.println("");
}

समय परिणाम कम हैं तो 1 मिलीसेकंड प्रत्येक पुनरावृत्ति को छोड़कर प्रत्येक पाँचवें पुनरावृत्ति को छोड़कर , जब समय परिणाम 225 मिलीसेकंड के आसपास होता है। कुछ इस तरह (नैनोसेकंड में):

BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
.
.
.

और इसी तरह..

सारांश:

  1. ग्रहण "बी" के साथ पूरी तरह से काम करता है
  2. नेटबीन्स में एक लाइन-रैपिंग समस्या है जिसे हल किया जा सकता है (क्योंकि समस्या ग्रहण में नहीं होती है) (बी ("बी") के बाद स्थान को जोड़ने के बिना)।

32
क्या आप अपनी शोध रणनीतियों के बारे में विस्तार से बता सकते हैं और फिर आखिरकार आपको यह पता लगाने के लिए कि लाइन-रैपिंग अपराधी कौन था? (मैं अपने जासूसी कौशल के बारे में उत्सुक हूं, वह है!)
सिल्फ़

12

हां, अपराधी निश्चित रूप से शब्द-लपेटन है। जब मैंने आपके दो कार्यक्रमों का परीक्षण किया, तो NetBeans IDE 8.2 ने मुझे निम्नलिखित परिणाम दिए।

  1. पहला मैट्रिक्स: ओ और # = 6.03 सेकंड
  2. दूसरा मैट्रिक्स: ओ और बी = 50.97 सेकंड

अपने कोड को बारीकी से देखते हुए आपने पहले लूप के अंत में एक लाइन ब्रेक का उपयोग किया है। लेकिन आपने दूसरे लूप में किसी भी लाइन ब्रेक का उपयोग नहीं किया। तो आप दूसरे लूप में 1000 अक्षरों वाले शब्द को प्रिंट करने जा रहे हैं। यह एक शब्द-रैपिंग समस्या का कारण बनता है। यदि हम बी के बाद एक गैर-शब्द चरित्र "" का उपयोग करते हैं, तो प्रोग्राम को संकलित करने में केवल 5.35 सेकंड लगते हैं । और अगर हम 100 मान या 50 मान पास करने के बाद दूसरे लूप में एक लाइन ब्रेक का उपयोग करते हैं, तो यह क्रमशः 8.56 सेकंड और 7.05 सेकंड लेता है।

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("B");
        }
        if(j%100==0){               //Adding a line break in second loop      
            System.out.println();
        }                    
    }
    System.out.println("");                
}

एक और सलाह यह है कि नेटबीन्स आईडीई की सेटिंग्स को बदलना। सबसे पहले, नेटबीन्स टूल्स पर जाएं और विकल्प पर क्लिक करें । उसके बाद Editor पर क्लिक करें और फ़ॉर्मेटिंग टैब पर जाएँ। फिर कहीं भी लाइन व्रैप ऑप्शन में सेलेक्ट करें । कार्यक्रम को संकलित करने में लगभग 6.24% कम समय लगेगा।

नेटबीन्स संपादक सेटिंग्स

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.