2012-03-16 7 views
7

IEnumerableがフードの下でIObservableとどのように異なるのか不思議です。私はプルとプッシュのパターンをそれぞれ理解していますが、C#はメモリの面でどのように処理するメモリ内の次のビットのデータを受け取るべきかを(IObservableのために)加入者に通知しますか?観察されたインスタンスは、加入者にプッシュするデータが変更されていることをどのように知っていますか。IEnumerableとIObservableの違いは何ですか?

私の質問は、私がファイルから行を読み込んで実行していたテストから来ています。ファイルは合計で約6Mbでした。

標準時撮影:4.7s、ライン:36587

Rxの時間は、撮影:0.68s、行:

36587は、どのように大規模なファイルの行ごとの上に通常の反復処理を改善することができRxのです?

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

このアプリケーションのベンチマーク時に通話の順序を切り替えると、RXはまだ高速ですか? – user7116

+0

時間が逆転しました!何らかの最適化が進行中です!実際、Rxは遅く(約5秒)実行されます。 – David

答えて

5

あなたが見ている動作は、ファイルをキャッシュするOSが反映されていることです。あなたがコールの順序を逆にすると、同様のスピードの違いが見えて、ちょうど入れ替えられたと思います。

ウォームアップを2,3回実行するか、またはそれぞれをテストする前にFile.Copyを使用して入力ファイルを一時ファイルにコピーすることで、このベンチマークを改善できます。この方法では、ファイルが "熱く"ならず、公正な比較ができます。

+0

修正。いくつかのキャッシュが起こっているように見えます。 – David

+0

10MBまたは25Mbのファイルでは速度に大きな違いはありません。その後、コンマでランダムに生成されたデータを100MB(最大のテスト済み)までケーキ(4倍のスピードアップ)で処理します。これには、実際の結果が与えられる前に各メソッドを3回実行することによってJITを「ウォームアップ」することが含まれます。ベンチマークと同様に、それはあなたのオペレーティング環境に特有のものです。 – user7116

1

私はCLRの内部最適化のいくつかの種類が見えていると思います。それはおそらくToObservableが内容をはるかに速く引き出すことができるように、2つの呼び出しの間にメモリ内のファイルの内容をキャッシュするでしょう...

編集:ああ、狂ったニックネームeeh ... @sixlettervariablesの方が速く、彼はおそらく正しいでしょう:CLRよりもむしろ最適化しているOSです。

関連する問題