2013-04-19 2 views
5

Ich habe eine Funktion, die durch die Saite läuft und nach Mustern sucht und Teile davon verändert. Ich kann es optimieren, indemist String.Contains() schneller als durch das gesamte Array von char in String gehen?

if (!text.Contains(pattern)) return; 

Einsetzen Aber, ich bin durch die ganze Reihe tatsächlich zu Fuß und Teile davon mit dem Muster verglichen wird, so ist die Frage, wie String.Contains() tatsächlich funktioniert? Ich weiß, dass es so eine Frage gab - How does String.Contains work?, aber die Antwort ist ziemlich unklar. Also, wenn String.Contains() durch das ganze Array von Zeichen geht und sie mit Mustern vergleicht, nach denen ich auch suche, würde es meine Funktion nicht wirklich schneller machen, aber langsamer.

Also, ist es eine gute Idee, solche Optimierungen zu versuchen? Und - ist es möglich, dass String.Contains() noch schneller als Funktion ist, die nur durch das ganze Array gehen und jedes einzelne Zeichen mit einem konstanten vergleichen? Hier

ist der Code:

public static char colorchar = (char)3; 

    public static Client.RichTBox.ContentText color(string text, Client.RichTBox SBAB) 
    { 
     if (text.Contains(colorchar.ToString())) 
     { 
      int color = 0; 
      bool closed = false; 
      int position = 0; 
      while (text.Length > position) 
      { 
       if (text[position] == colorchar) 
       { 
        if (closed) 
        { 
         text = text.Substring(position, text.Length - position); 
         Client.RichTBox.ContentText Link = new Client.RichTBox.ContentText(ProtocolIrc.decode_text(text), SBAB, Configuration.CurrentSkin.mrcl[color]); 
         return Link; 
        } 

        if (!closed) 
        { 
         if (!int.TryParse(text[position + 1].ToString() + text[position + 2].ToString(), out color)) 
         { 
          if (!int.TryParse(text[position + 1].ToString(), out color)) 
          { 
           color = 0; 
          } 
         } 
         if (color > 9) 
         { 
          text = text.Remove(position, 3); 
         } 
         else 
         { 
          text = text.Remove(position, 2); 
         } 
         closed = true; 
         if (color < 16) 
         { 
          text = text.Substring(position); 
          break; 
         } 
        } 
       } 
       position++; 
      } 
     } 
     return null; 
    } 
+0

Sie müssten den Rest des Codes (eine Gliederung) posten. Aber ja, wahrscheinlich machst du hier Doppelarbeit. –

+4

Warum tätest du beide Ansätze in einer for-Schleife? – Habib

+0

@Habib das ist keine schlechte Idee :) – Petr

Antwort

3

Wenn string.Contains nicht schnell genug ist, dann ist es sehr unwahrscheinlich, dass eine Optimierung einer gleichwertigen Methode schnell genug sein wird.

Erstens, sind Sie sicher, dass string.Contains eigentlich nicht schnell genug ist? Ich kann es kaum glauben, es sei denn, du machst eine massive String-Bearbeitung.

Zweitens, wenn Sie sicher, dass dies sind, dann müssen Sie auf andere Art und Weise sehen, Ihr Ziel zu erreichen, möglicherweise eine Art von Indexierungs Dienstprogramm wie Lucene.Net mit

+0

eh, ich denke, es ist etwas falsch mit meiner Frage, denn das ist nicht, was ich gefragt habe .. Ich meine nicht, dass String.Contains() nicht schnell genug ist - ich möchte wissen, ob das Hinzufügen zu meiner Funktion es schneller machen könnte oder nicht (die ganze Funktion), weil ich glaube, dass ich dasselbe mache String.Contains() tut, so würde es zweimal tun – Petr

+0

@Petr Besten Weg, um herauszufinden, ob Ihr Code schneller wird oder nicht, ist es, die Änderung dann Profil es :) – Patashu

+0

Wow, das ist naiv. Ein einfacher Boyer-Moore String-Suchalgorithmus wird "string.Contains" große Zeit übertreffen. – leppie

0

Ja.

Und hat keinen Fehler (ahhm ...).

Es gibt bessere Möglichkeiten für die Suche nach mehreren Teilstrings in sehr langen Texten, aber für die meisten gängigen Anwendungen ist String.Contains (oder IndexOf) das beste.

IIRC auch die Quelle der String.Contains in .NET gemeinsamen Quellen verfügbar ist

Ach ja, und wenn Sie einen Leistungsvergleich möchten, können Sie einfach Ihre genaue ähnlich der Use-Case

0

prüfen messen Post How does string.contains work

ich denke, dass Sie nicht in der Lage sein wird, einfach nichts zu tun schneller als String.Contains, es sei denn, Sie Standard-CRT-Funktion wcsstr verwenden möchten, in msvcrt.dll, was nicht so einfach ist,

1

Kurze Antwort ist, dass Ihre Optimierung überhaupt keine Optimierung ist.
Grundsätzlich String.Contains(...) gibt nur String.IndexOf(..) >= 0
Sie Ihre alogrithm verbessern könnte:

int position = text.IndexOf(colorchar.ToString()...); 
if (-1 < position) 
{ /* Do it */ } 
0

Sofern Sie Ihre Anwendung profiliert haben und festgestellt, dass die Linie mit String.Contains ist ein Flaschenhals, Sie sollte nicht jeder solche vorzeitigen Optimierungen. Es ist viel wichtiger, die Absicht Ihres Codes klar zu halten.

Ans, während es gibt viele Möglichkeiten, die Methoden in der implementieren.NET-Basisklassen sollten Sie davon ausgehen, dass die Standardimplementierungen für die meisten Anwendungsfälle der Benutzer optimal genug sind. Zum Beispiel könnte jede (zukünftige) Implementierung von .NET die x86-spezifischen Anweisungen für Zeichenfolgenvergleiche verwenden. Das wäre dann immer schneller als das, was man in C# machen kann.

Wenn Sie wirklich sicher sein wollen, ob Ihr benutzerdefinierter Zeichenfolgenvergleichscode schneller als String.Contains ist, müssen Sie beide mit vielen Iterationen messen, jede mit einer anderen Zeichenfolge. Zum Beispiel mit der Stopwatch class, um die Zeit zu messen.

0

Wenn Sie jetzt die Details, die Sie für Optimierungen verwenden können (nicht nur einfache enthält überprüfen) sicher, können Sie Ihre Methode schneller als string.Contains, sonst - nicht.

Verwandte Themen