2012-03-16 33 views
7

मुझे उत्सुकता है कि कैसे IEnumerableIObservable से हुड के नीचे अलग है। मैं क्रमशः पुल और पुश पैटर्न को समझता हूं लेकिन सी #, स्मृति आदि के मामले में, ग्राहकों को सूचित करता है (IObservable के लिए) कि इसे प्रक्रिया में स्मृति के अगले डेटा को प्राप्त करने के लिए प्राप्त करना चाहिए? मनाए गए उदाहरण को कैसे पता चलता है कि ग्राहकों को धक्का देने के लिए डेटा में बदलाव आया है।iNumerable कैसे हुड के नीचे IObservable से भिन्न है?

मेरा प्रश्न एक परीक्षण से आता है जो मैं फ़ाइल से लाइनों में पढ़ रहा था। फाइल कुल में लगभग 6 एमबी थी।

मानक समय लिया गया: 4.7s, लाइनों: 36587

आरएक्स लिए गए समय: 0.68s, लाइनों: 36587

आरएक्स बड़े पैमाने पर फ़ाइल की पंक्तियों में से प्रत्येक पर एक सामान्य यात्रा सुधार करने में सक्षम कैसे है ?

private static void ReadStandardFile() 
{ 
    var timer = Stopwatch.StartNew(); 
    var linesProcessed = 0; 

    foreach (var l in ReadLines(new FileStream(_filePath, FileMode.Open))) 
    { 
     var s = l.Split(','); 
     linesProcessed++; 
    } 

    timer.Stop(); 

    _log.DebugFormat("Standard Time Taken: {0}s, lines: {1}", 
     timer.Elapsed.ToString(), linesProcessed); 
} 

private static void ReadRxFile() 
{ 
    var timer = Stopwatch.StartNew(); 
    var linesProcessed = 0; 

    var query = ReadLines(new FileStream(_filePath, FileMode.Open)).ToObservable(); 

    using (query.Subscribe((line) => 
    { 
     var s = line.Split(','); 
     linesProcessed++; 
    })); 

    timer.Stop(); 

    _log.DebugFormat("Rx Time Taken: {0}s, lines: {1}", 
     timer.Elapsed.ToString(), linesProcessed); 
} 

private static IEnumerable<string> ReadLines(Stream stream) 
{ 
    using (StreamReader reader = new StreamReader(stream)) 
    { 
     while (!reader.EndOfStream) 
      yield return reader.ReadLine(); 
    } 
} 
+0

यदि आप इस एप्लिकेशन को बेंचमार्क करते समय अपनी कॉल का ऑर्डर स्विच करते हैं, तो क्या आरएक्स अभी भी तेज़ है? – user7116

+0

टाइम्स उलटा हुआ है! कुछ प्रकार का अनुकूलन चल रहा है! वास्तव में, आरएक्स एक धीमा (लगभग 5 एस) चलाता है। – David

उत्तर

5

मेरा झुकाव वह व्यवहार है जिसे आप देख रहे हैं ओएस फाइल को कैश कर रहा है। मैं कल्पना करूंगा कि अगर आप कॉल के आदेश को उलट देते हैं तो आप गति में एक समान अंतर देखेंगे, बस बदल दिया है।

आप कुछ गर्म-अप रन करके या प्रत्येक फ़ाइल का परीक्षण करने से पहले File.Copy का उपयोग करके इनपुट फ़ाइल को एक अस्थायी फ़ाइल में कॉपी करके इस बेंचमार्क को बेहतर बना सकते हैं। इस तरह फ़ाइल "गर्म" नहीं होगी और आपको उचित तुलना मिलेगी।

+0

सही। हाँ ऐसा लगता है कि कुछ कैशिंग हो रहा है। – David

+0

मुझे 10 एमबी या 25 एमबी की फाइल के लिए उनकी गति में कोई सराहनीय अंतर नहीं मिलता है, और इसके बाद मानक कोमा के साथ यादृच्छिक रूप से जेनरेट किए गए डेटा के 100 एमबी (सबसे बड़ा परीक्षण) तक केक (4x स्पीडअप) लेता है। इसमें जेआईटी को इसके वास्तविक परिणाम देने से पहले प्रत्येक विधि 3x चलाने से "गर्म" करने की इजाजत दी गई थी। किसी भी बेंचमार्क के साथ, यह आपके ऑपरेटिंग वातावरण के लिए विशिष्ट होगा। – user7116

1

मुझे संदेह होगा कि आप सीएलआर के किसी प्रकार का आंतरिक अनुकूलन देख रहे हैं। यह शायद दो कॉल के बीच स्मृति में फ़ाइल की सामग्री को कैश करता है ताकि ToObservable सामग्री को तेज़ी से खींच सके ...

संपादित करें: ओह, पागल उपनाम ईह के साथ अच्छा सहयोगी ... @sixlettervariables तेज़ था और वह शायद सही है: यह ओएस है जो सीएलआर की तुलना में अनुकूलन कर रहा है।