2015-05-02 11 views
6

के साथ काम करते समय सीपीयू और/या रैम उत्पादकता कल मैं एक परीक्षा समस्या को हल कर रहा था, जब कुछ बहुत दिलचस्प (कम से कम मेरे लिए) पाया गया। कार्यक्रम फैक्टोरियल (बहुत बड़े लोगों) के लिए है और परिणाम यह है कि संख्या के अंत में कितने शून्य हैं (कुछ मामलों में 2500 शून्य ..)। तो मैंने जो किया वह मैंने किया, लेकिन पाया कि 100 000 जैसे नंबर दर्ज करते समय परिणाम को आउटपुट करने के लिए वास्तव में 1;30 - 1;33min लगता है। मैंने सोचा क्योंकि यह मेरे सीपीयू के कारण है (यह बहुत तेज़ नहीं है)। मैंने अपने कुछ दोस्तों को .exe को यह कोशिश करने के लिए भेजा है क्योंकि जब हम प्रदर्शन के बारे में बात कर रहे हैं तो उनके पास बहुत अच्छे पीसी हैं - बिल्कुल वही परिणाम (1;33min)।बड़े पूर्णांक

मेरा प्रश्न यह है कि कार्य को हल करने का समय क्यों है। मुझे पता है कि मेरे कोर को लिखने के बेहतर तरीके हैं इसलिए इसमें नहीं लगेगा, लेकिन शुरुआती प्रोग्रामर के रूप में समझना मेरे लिए बहुत महत्वपूर्ण है।

static void Main() 
     { 
      int num = int.Parse(Console.ReadLine()), 
       zeroCounter = 0; 
      BigInteger fact = 1; 
      var startTime = DateTime.Now; 

      Console.WriteLine(); 

      for (int i = 1; i <= num; i++) 
      { 
       fact *= i; 
       Console.Write("\r{0}", DateTime.Now - startTime); 
      } 
      BigInteger factTarget = fact; 
      while (factTarget % 10 == 0) 
      { 
       factTarget /= 10; 
       zeroCounter++; 
       Console.Write("\r{0}", DateTime.Now - startTime); 
      } 
      Console.WriteLine(); 
      Console.WriteLine("Result is number with {0} zeros.", zeroCounter); 
      Console.WriteLine(); 
      Console.WriteLine("Finished for: {0}", DateTime.Now - startTime); 
      Console.WriteLine(); 
      Console.WriteLine("\nPres any key to exit..."); 
      Console.ReadKey(); 
     } 

मैं बहुत माफी चाहता हूँ यह पूछने के लिए गलत जगह है, मैं मैं इससे पहले कि मैं इस पोस्ट के लिए क्या देख रहा था खोजने के लिए मेरे सबसे अच्छे किया है: तो यहाँ मेरी कोड है।

+5

आपका कोड लूप के प्रत्येक पुनरावृत्ति पर कंसोल के लिए एक पंक्ति उत्सर्जित कर रहा है। गणना समय एक पुनरावृत्ति निष्पादित करने के लिए समय का एक छोटा सा अंश होगा क्योंकि एक लाइन आउटपुट करने के लिए आवश्यक सिस्टम कॉल तुलनात्मक रूप से बहुत धीमी होगी। I/O प्रक्रियाएं आमतौर पर प्रोसेसर की गति से बंधी नहीं होती हैं, लेकिन अन्य कारकों से इसलिए अधिकांश पीसी प्रोग्राम को एक ही समय में निष्पादित करेंगे। गणना गणना के पहले और बाद में आउटपुट के साथ प्रयोग फिर से प्रयास करें। –

+2

अत्यधिक @Hobo Sapiens के रूप में लिखा है - इसके अतिरिक्त आप स्टॉपवॉच क्लास (https://msdn.microsoft.com/en-US/library/system.diagnostics.stopwatch%28v=vs.110%29.aspx) का उपयोग करना चाह सकते हैं। समय को मापने के लिए क्योंकि यह केवल आपके कोड को निष्पादित करने के लिए आवश्यक समय को मापता है। –

+0

मैं 'स्टॉपवॉच' का उपयोग करने के लिए @ पियट्रिपियेटर की सिफारिश से सहमत हूं। उस ने कहा, 'स्टॉपवॉच' उपायों को अनिवार्य रूप से समय सीमा समाप्त हो गई है क्योंकि 'डेटटाइम.अब' रिकॉर्डिंग होगी। बड़ा अंतर यह है कि ए) 'स्टॉपवॉच' अधिक सटीक हो सकता है (पीसी के आधार पर), और बी) यह भिन्नता के अधीन नहीं है जो हो सकता है उदा। पीसी की घड़ी को रीसेट करके (जो कि अधिकांश पीसी पर स्वचालित रूप से और समय-समय पर होता है), या टाइमज़ोन में परिवर्तन ('UtcNow' के बजाय' Utc' का उपयोग करते समय)। इस परीक्षण के दौरान होने वाले किसी भी व्यक्ति की बाधा कम है, लेकिन यह अभी भी एक अच्छा सुझाव है। –

उत्तर

0

क्या होता है कि कोर या प्रोसेसर पीसी में आंतरिक बसों का एक निश्चित आकार होता है, जो डेटा संग्रहित करता है। प्रोसेसर की तुलना में रैम की गति 10-1000 गुना धीमी है। कैश मेमोरी नामक कुछ भी है, लेकिन कैश मेमोरी का आकार बांध छोटा है। तो आपके पीसी में आपके पास कितनी बड़ी रैम है, यह अभी भी धीमा हो जाएगा और समय लगेगा। Coz जब यह उच्च संख्या तक पहुंचता है, तो संख्याओं को स्मृति में पढ़ने और लिखने के लिए समय लगता है।

प्लस प्रत्येक बार स्क्रीन पर लिखने के लिए कुछ समय खा जाता है।

5

जो चीज़ मैं तुरंत आपके कोड के बारे में नोटिस करता हूं वह यह है कि आपने अपने कम्प्यूटेशनल लूप में Console.WriteLine() कथन शामिल किए हैं।

तथ्य यह है कि, I/O कम्प्यूटर के लिए आदर्श परिस्थितियों के तहत भी गणना करने के लिए धीमे कंप्यूटर के लिए धीमा है। और मैं यह नहीं कहूंगा कि विंडोज कंसोल विंडो उस विशेष प्रकार के I/O का विशेष रूप से प्रभावी कार्यान्वयन है। इसके अलावा, I/O सीपीयू पर कम निर्भर होता है और मशीन से मशीन तक मेमोरी अंतर होता है।

दूसरे शब्दों में, मुझे लगता है कि आप मुख्य रूप से I/O थ्रूपुट को माप रहे हैं और कम्प्यूटेशनल थ्रूपुट नहीं माप रहे हैं, और इसलिए मशीनों के बीच लगातार परिणाम देखने में आश्चर्य की बात नहीं है।

इसके लायक होने के लिए, जब मैं अपने लैपटॉप पर अपना उदाहरण चलाता हूं, अगर मैं आउटपुट अक्षम करता हूं तो मैं लगभग एक मिनट में गणना पूर्ण कर सकता हूं। यदि मैं कोड का उपयोग करता हूं तो मुझे आपके 1:30 समय के करीब कुछ मिलता है।


संपादित करें: मैं भी हंस Passant से जवाब सलाह देते हैं। मेमोरी I/O अभी भी I/O है और जैसा कि मैंने उपरोक्त वर्णन किया है, सीपीयू की गति से मशीन से मशीन तक बहुत कम चर है। यह मेरी आशा है कि उपर्युक्त सामान्य उद्देश्य वर्णन अंतर कहां हो सकता है (प्रश्न में प्रत्येक मशीन तक पहुंच के बिना, को सुनिश्चित करने के लिए वास्तव में कोई तरीका नहीं है), लेकिन हंस का उत्तर प्रदान करता है विशेष रूप से स्मृति I/O मुद्दे के बारे में कुछ बहुत अच्छी जानकारी है और पढ़ने के लिए बहुत अधिक मूल्यवान है।

+0

मैंने लिखने के बिना कोशिश की है और नतीजा यह है कि: 00: 01: 23.5856140' के लिए समाप्त हुआ - हाँ, आप सही थे। लेकिन सभी परिचालन करने का समय भी अलग पीसी के लिए समान है जो मेरे लिए risterains mistery है। : डी – Kadiyski

3

अब समय 00:01:23 है।5856140

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

आपके प्रोग्राम में मेरे लैपटॉप पर 57 सेकंड लगते हैं, मुझे पता है कि इसमें पीसी 3-12800 रैम है। जिसमें 12800 एमबी/सेकंड की चोटी हस्तांतरण दर है, सीएएस विलंबता दें या मुझे ले लो (मुझे मेरा पता नहीं है)। इसलिए हम अपने और अपने दोस्त की मशीन पर राम गति की गणना कर सकते हैं:

1:23 = 83 सेकंड, 57/83 x 12800 = 8790 MB/से।

कौन सा PC3-8500 के लिए एक pretty close match है। व्हाइट-बॉक्स मशीनों में एक रन-ऑफ-द-मिल रैम गति बहुत आम है, जिस तरह से आप डेल जैसे विक्रेता से मिलेंगे। आपके मित्र का तेजी से पीसी एक टोस्टर का एक सा, धीरे उसे इसे तोड़ने :)


Fwiw, क्यों अत्यधिक upvoted पोस्ट की गति पर एक प्रभाव के प्रति ज्यादा नहीं है और साथ ही एक विवरण का उपयोग कर सकते है। आपके प्रोग्राम का उपयोग करने वाली कंसोल विंडो किसी अन्य प्रक्रिया के स्वामित्व में है। Conhost.exe, आप इसे वापस Taskman.exe के प्रक्रिया टैब में देख सकते हैं। यह खिड़की को स्क्रॉल करने और खिड़की को पेंट करने का ख्याल रखता है, हुड के तहत आपका प्रोग्राम विंडो को अपडेट करने के लिए कहने के लिए प्रक्रिया-इंटरऑप का उपयोग करता है।

यह तब होता है जबकि अपने कार्यक्रम एक और धागा पर, चल रहा है, तो अपने कार्यक्रम केवल फंस-जाता है जब यह Conhost.exe firehoses, अद्यतन तेजी से इसे संभाल कर सकते हैं भेज दिया। तो, अपने कार्यक्रम की शुरुआत में आप अभी भी तेज़ हैं और नीचे गिर जाएंगे। लेकिन जब अंकों की संख्या बड़ी नहीं बढ़ती है और आपके गुणा धीमे होने लगते हैं। कुल मिलाकर, मंदी उस महान नहीं है।

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