2013-07-10 11 views
5

Poiché non c'è maiuscole e minuscole string.Contains() (esiste ancora una versione senza distinzione tra maiuscole e minuscole di string.Equals() che mi sconcerta, ma divago) in .NET, Che cos'è le differenze di prestazioni tra l'utilizzo di RegEx.IsMatch() e l'utilizzo di String.ToUpper().Contains()?RegEx.IsMatch() rispetto a String.ToUpper(). Contains() prestazioni

Esempio:

string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion"; 

bool containsString = RegEx.IsMatch(testString, "string", RegexOptions.IgnoreCase); 
bool containsStringRegEx = testString.ToUpper().Contains("STRING"); 

Ho sempre sentito dire che string.ToUpper() è una chiamata molto costoso quindi ho rifuggire da usando quando voglio fare string.Contains() paragoni, ma come si fa RegEx.IsMatch() confronto in termini di prestazioni?

Esiste un approccio più efficiente per effettuare tali confronti?

+4

Hai provato a utilizzare [Cronometro] (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx)? – Sayse

+2

L'unico modo per sapere quale è più veloce è eseguirli entrambi e cronometrarli. Questo potrebbe aiutare: http://stackoverflow.com/questions/457605/how-to-measure-code-performance-in-net – kevingessner

+3

Che dire di 'testString.IndexOf (" string ", StringComparison.CurrentCultureIgnoreCase)> = 0'? –

risposta

16

Ecco un benchmark

using System; 
using System.Diagnostics; 
using System.Text.RegularExpressions; 

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     Stopwatch sw = new Stopwatch(); 

     string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion"; 

     sw.Start(); 
     var re = new Regex("string", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); 
     for (int i = 0; i < 1000000; i++) 
     { 
      bool containsString = re.IsMatch(testString); 
     } 
     sw.Stop(); 
     Console.WriteLine("RX: " + sw.ElapsedMilliseconds); 

     sw.Restart(); 
     for (int i = 0; i < 1000000; i++) 
     { 
      bool containsStringRegEx = testString.ToUpper().Contains("STRING"); 
     } 


     sw.Stop(); 
     Console.WriteLine("Contains: " + sw.ElapsedMilliseconds); 

     sw.Restart(); 
     for (int i = 0; i < 1000000; i++) 
     { 
      bool containsStringRegEx = testString.IndexOf("STRING", StringComparison.OrdinalIgnoreCase) >= 0 ; 
     } 


     sw.Stop(); 
     Console.WriteLine("IndexOf: " + sw.ElapsedMilliseconds); 
    } 
} 

I risultati sono stati

IndexOf (183ms)> Contiene (400mS)> Regex (477ms)

(tempi di uscita aggiornato utilizzando il Regex compilato)

+1

Risultati sul mio PC: RX: 3032 Contiene: 385 IndexOf: 97 (build non ottimizzato sotto mono) (PS ho fatto il regex precompilato) – sehe

+0

@sehe - Grazie per la modifica e dati. – keyboardP

+0

Che dire di Jitter? – ata

10

C'è un'altra versione utilizzando String.IndexOf(String,StringComparison) che potrebbe essere più efficiente di uno dei due hai suggerito:

string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion"; 
bool contained = testString.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0; 

Se avete bisogno di un confronto sensibile cultura, utilizzare CurrentCultureIgnoreCase invece di OrdinalIgnoreCase.

0

Mi aspetto che RegEx.match sia lento in base all'esperienza personale con parser di espressioni regolari in generale. Ma come molti hanno menzionato, la profilazione è il modo migliore per scoprirlo di sicuro. Ho dovuto risolvere problemi di prestazioni relativi ai parser di espressioni regolari, toLower e toUpper non sono mai tornato a mordermi.

Problemi correlati