2017-12-18 11 views
1

Ich bekomme große Volumendaten über TCP. Es gibt zwei Arten von XML-Paketen in Daten. Ich muss es so schnell wie möglich verarbeiten.C# Code-Optimierung für große Datenmengen

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

und

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

Irgendwann Pakete nicht XML-Deklaration haben.

Dies ist alter Code.

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() war in über 26% der Code-CPU Zeit.

Unten ist der optimierte Code. Es verbesserte Leistung um 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() jetzt 8% der CPU-Zeit nimmt.

Ich möchte Code weiter optimieren. Jeder Vorschlag ist willkommen.

Vielen Dank im Voraus.

+0

Sie Ihren Code parallelisieren können, um XML parallel zu verarbeiten. – Jepessen

+0

Sie können versuchen, die Funktion 'StringBuilder.ToString (int startIndex, int length) 'zu verwenden, um nur einen Teil der Zeichenfolge _ (z. B. die ersten 105 Zeichen oder die letzten 50 Zeichen) _ zu konvertieren. Dann sollten die Operationen mindestens ein bisschen schneller sein. – Julo

+0

Zeigen Sie, wie deklarieren und füllen Sie 'sb' – Backs

Antwort

1

Sie können versuchen, zu überprüfen, ob der Zeichenfolgengenerator mit der angegebenen Zeichenfolge endet, indem Sie Schleife und Indexer verwenden, und prüfen, ob dies die Leistung verbessert. Zum Beispiel:

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; 
    } 
} 

Verbrauch:

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

Ich habe versucht mit anderen Datenstruktur, jetzt mit der Liste und es funktioniert perfekt. – Manjoor

+0

Gut zu wissen (obwohl intern StringBuilder auch eine Liste von Zeichen ist). – Evk

Verwandte Themen