2017-09-07 11 views
0

これは非特定コードの問題であることを認識しています。しかし、私は答えを持つ人々がこのフォーラムにいると思う。処理レコードの速度

< 100バイトの大量のレコードを、TCPを介してミリ秒あたり10の割合で受信しています。

私はデータを解析して処理する必要があり、それは100マイクロ秒かかるので、私はかなり上回っています。

100マイクロ秒が大きいようですか?

ここでは、LINQで行う処理の種類の例を示します。本当に便利ですが、本質的に遅いのですか?

public void Process() 
    { 
     try 
     { 
      int ptr = PayloadOffset + 1; 
      var cPair = MessageData.GetString(ref ptr, 7); 
      var orderID = MessageData.GetString(ref ptr, 15); 

      if (Book.CPairs.ContainsKey(cPair)) 
      { 
       var cPairGroup = Book.CPairs[cPair]; 
       if (cPairGroup.BPrices != null) 
       {      
        cPairGroup.BPrices.ForEach(x => { x.BOrders.RemoveAll(y => y.OrderID.Equals(orderID)); }); 
        cPairGroup.BPrices.RemoveAll(x => x.BOrders.Count == 0); 
       } 
      } 
     } 
    } 

    public class BOrderGroup 
    { 
     public double Amount; 
     public string OrderID; 
    } 

    public class BPriceGroup 
    { 
     public double BPrice; 
     public List<BOrderGroup> BOrders; 
    } 
    public class CPairGroup 
    { 
     public List<BPriceGroup> BPrices; 
    } 

    public static Dictionary<string, CPairGroup> CPairs; 
+2

いいえ、LINQは「本質的に遅い」ではありません。 – Amy

+0

データを処理するのに100マイクロ秒かかったとはどのように判断しましたか?サブミリ秒の時間分解能はどのようになっていますか? –

+0

あなたのクラスの定義も表示 – Milney

答えて

3

他にも述べたように、LINQは本来遅いわけではありません。しかし、それは同等の非LINQコードよりも遅くなる可能性があります(これは、Roslynチームがcoding conventionsの下で "LINQを避ける"ガイドを持っている理由です)。

これはあなたの熱いパスであり、あなたはおそらく、このような方法でロジックを実装する必要がありますよりも、マイクロ秒ごと必要がある場合:

public void Process() 
{ 
    try 
    { 
     int ptr = PayloadOffset + 1; 
     var cPair = MessageData.GetString(ref ptr, 7); 
     var orderID = MessageData.GetString(ref ptr, 15); 

     if (Book.CPairs.TryGetValue(cPair, out CPairGroup cPairGroup) && cPairGroup != null) 
     { 
      for (int i = cPairGroup.BPrices.Count - 1; i >= 0; i--) 
      { 
       var x = cPairGroup.BPrices[i]; 
       for (int j = x.BOrders.Count - 1; j >= 0; j--) 
       { 
        var y = x.BOrders[j]; 
        if (y.OrderID.Equals(orderID)) 
        { 
         x.BOrders.RemoveAt(j); 
        } 
       } 
       if (x.BOrders.Count == 0) 
       { 
        cPairGroup.BPrices.RemoveAt(i); 
       } 
      } 
     } 
    } 
} 

主なポイント:

  • TryGetValue
  • を使用して二重の辞書検索を避けるに
  • 単一反復以上cPairGroup.BPrices
  • 逆方向反復による構造の変更s
  • このコードに追加のヒープ割り当てが含まれないようにしてください。
+0

私のためのソリューションを作成する時間をとってもいただきありがとうございます。私はこれを明日実装してテストし、その結果を報告します。もう一度、ありがとう。 – ManInMoon

+0

良い実装。これはC#と妥当な読みやすさでできる限り速いです。 –

関連する問題