2017-12-18 268 views
1

我通過TCP獲取大容量數據。數據中有2種類型的XML數據包。我需要儘快處理它。c#大量數據的代碼優化

<?xml version="1.0" encoding="UTF-8"?><xsi:Event> .... [dynamic length data] .... </xsi:Event> 

<?xml version="1.0" encoding="UTF-8"?><ChannelHeartBeat xmlns="http://schema.broadsoft.com/xsi"/> 

有時包沒有XML聲明。

這是舊代碼。

char c = (char)streamReader.Read(); 
sb.Append(c); 

if(sb.ToString().EndsWith("</xsi:Event>",StringComparison.OrdinalIgnoreCase)) 
{ 
    .... 
    sb.Clear(); 
} 

if(sb.ToString().EndsWith("<ChannelHeartBeat xmlns=\"http://schema.broadsoft.com/xsi\"/>", StringComparison.OrdinalIgnoreCase)) 
{ 
    .... 
    sb.Clear(); 

} 

ToString()在上述代碼中佔用了26%的CPU時間。

下面是優化代碼。它將性能提高了30%

char c = (char)streamReader.Read(); 
    sb.Append(c); 
    n++; 
    if (n > 60) 
    { 
     if (c == '>') 
     {   
      if (n < 105) 
      { 
       string temp = sb.ToString(); 
       if (temp.EndsWith("<ChannelHeartBeat xmlns=\"http://schema.broadsoft.com/xsi\"/>", StringComparison.OrdinalIgnoreCase)) 
       { 
       sb.Clear(); 
       n = 0; 
       } 
      } 
      if (n > 700) 
      { 
       string temp = sb.ToString(); 
       if (temp.EndsWith("</xsi:Event>", StringComparison.OrdinalIgnoreCase)) 
       { 
       sb.Clear(); 
       n = 0; 
       } 
      } 
     } 
    } 
} 

ToString()現在佔用8%的CPU時間。

我想進一步優化代碼。任何建議都是值得歡迎的。

在此先感謝。

+0

可以並行代碼,以處理XML並行。 – Jepessen

+0

您可以嘗試使用'StringBuilder.ToString(int startIndex,int length)'函數僅轉換部分字符串_(例如前105個字符或後50個字符)_。那麼操作應該至少快一點。 – Julo

+0

顯示,你如何聲明並填充'sb' – Backs

回答

1

您可以嘗試檢查字符串生成器是否以給定的字符串結尾並使用循環和索引器,並查看是否可以提高性能。例如:

public static class Extensions { 
    public static bool EndsWith(this StringBuilder sb, string target, bool caseInsensetive = false) { 
     // if sb length is less than target string 
     // it cannot end with it 
     if (sb.Length < target.Length) 
      return false; 
     var offset = sb.Length - target.Length;    
     for (int i = sb.Length - 1; i >= offset; i--) { 
      var left = sb[i]; 
      var right = target[i - offset]; 
      // conver to upper-case for insensetive comparision 
      // if necessary 
      if (caseInsensetive) { 
       left = Char.ToUpper(left, CultureInfo.InvariantCulture); 
       right = Char.ToUpper(right, CultureInfo.InvariantCulture); 
      } 
      // fail fast 
      if (left != right) 
       return false; 
     } 
     return true; 
    } 
} 

用法:

const string HeartBeatEnding = "<ChannelHeartBeat xmlns=\"http://schema.broadsoft.com/xsi\"/>"; 
const string EventEnding = "</xsi:Event>"; 

char c = (char)streamReader.Read(); 
sb.Append(c); 
if (sb.EndsWith(EventEnding)) { 
    // do stuff 
} 
else if (sb.EndsWith(HeartBeatEnding)) { 
    // do stuff 
} 
+0

我嘗試了不同的數據結構,現在使用列表和它完美的作品。 – Manjoor

+0

很高興知道(雖然內部StringBuilder也是字符列表)。 – Evk