2014-05-15 55 views
0

我需要儘可能快地解析FIX消息。這是一種解析FIX格式的大字符串的有效方法嗎?

我的方法如下。我保留了FP_FixString中的FixString的引用,然後按順序獲取Tag值,因爲我需要它們。

修復信息大約4K字符和約100重複組3我需要提取標籤。

我是否儘可能有效地做到這一點?從字符串構建和解析角度來看?

pubic FixParser 
{ 
     string FP_FixString; 
     int FP_m; 
     int FP_Lastm; 

     public void Go() 
     { 
      using (StreamReader reader = new StreamReader(new GZipStream(File.OpenRead(@"L:\Logs\FIX.4.2-D.messages.current.log.20140512T.gz"), CompressionMode.Decompress))) 
      { 
       string line = ""; 
       while ((line = reader.ReadLine()) != null) 
       { 

         InitiateFixParse(ref line); 

         string Symbol; 
         if (!GetTagString(55, out Symbol)) 
         return; 

         //DO ALL OTHER PROCESSING OF TAGS HERE 
       } 
     } 


     public void InitiateFixParse(ref string fixString) 
     { 
      FP_Lastm = fixString.Length - 1; 
      FP_FixString = fixString; 
      FP_m = 0; 
     } 

     public bool IsEndMark() 
     { 
      if (FP_m>=FP_Lastm || FP_FixString[FP_m].Equals('\x01')) 
       return true; 

      return false; 
     } 

     public bool NextTag(out int Tag, out string ValueString) 
     { 
      Tag = 0; 
      ValueString = ""; 
      if(FP_m>=FP_Lastm) 
       return false; 

      string TagString = ""; 
      bool GettingTag=true; 
      while (!IsEndMark()) 
      { 
       if (FP_FixString[FP_m].Equals('=')) 
       { 
        GettingTag = false; 
        FP_m++; 
       } 
       if(GettingTag) 
        TagString = TagString + FP_FixString[FP_m]; 
       else 
        ValueString = ValueString + FP_FixString[FP_m]; 
       FP_m++; 
      } 

      Tag=int.Parse(TagString); 
      FP_m++; //Start of next Tag 

      return true; 
     } 

     public bool GetTagString(int Tag, out string ValueString) 
     { 
      //bool FountIt = false; 
      int aTag; 
      string aValueString; 
      while (NextTag(out aTag, out aValueString)) 
      { 
       if (aTag == Tag) 
       { 
        ValueString = aValueString; 
        return true; 
       } 
      } 

      ValueString = ""; 
      return false; 
     } 
} 
+0

你有沒有剖析你的代碼,並消除了剖析器指出的瓶頸? – DumbCoder

回答

0

如果您正在處理非常大的文件,您希望儘可能避免GC壓力,如前所述。 StringBuilder可以幫助你,但你仍然在創建一個StringBuilder實例。一些快速的勝利:

if (GettingTag) 
{ 
    //TagString = TagString + FP_FixString[FP_m]; 
    Tag = Tag * 10 + ((byte)FP_FixString[FP_m] -48); 
}// This reduces time by about 40% 

//Tag = int.Parse(TagString); 

下面的代碼減少了時間甚至進一步(減少了原來的50%):

int valueStart = 0; 
while (!IsEndMark()) 
{ 
    if (FP_FixString[FP_m].Equals('=')) 
    { 
     GettingTag = false; 
     FP_m++; 
     valueStart = FP_m; 
    } 
    if (GettingTag) 
    { 
     //TagString = TagString + FP_FixString[FP_m]; 
     Tag = Tag * 10 + ((byte)FP_FixString[FP_m] -48); 
    } 
    //else 
     //ValueString = ValueString + FP_FixString[FP_m]; 
    FP_m++; 
} 
ValueString = FP_FixString.Substring(valueStart, FP_m - valueStart); 

//Tag = int.Parse(TagString); 
FP_m++; //Start of next Tag 

我還沒有看,該代碼進一步。

+0

不錯的建議!標籤是否設置爲初始值0? – ManInMoon

+0

是的。需要Tag = 0,但它工作得很好。我的實際數據得到了25%的提高。這非常重要。謝謝 – ManInMoon

+0

是的,對不起,其餘的代碼保持原樣。我只顯示了我更改的代碼。 – Domc

1

我唯一的第一眼的建議是,以取代在循環中完成字符串連接,如TagString = TagString + FP_FixString[FP_m];,與StringBuilders即

StringBuilder sb = new StringBuilder(); 
while (!IsEndMark()) 
{ 
    sb.append(FP_FixString[FP_m]); 
} 
TagString = sb.ToString(); 

爲StringBuilder的是比迴路串聯更有效。通常的注意事項適用。我同意@DumbCoder的分析是一個好主意。另一方面,如果可能的話(例如,如果你不試圖解析自動創建的日誌)存儲消息的FIXml表示並使用xpath來提取數據可能會更好,因爲它可以幫助解決一些重複分組問題,或者更確切地說,它爲我在這裏做了!

相關問題