2012-08-25 20 views
9

Sono rimasto scioccato da quanto sia lento lo DateTime.Parse. Questo codice richiede circa 100 secondi per essere eseguito; se uso la versione regex ci vogliono 100 millisecondi. Cosa sta succedendo qui?Perché DateTime.Parse è lento?

Stopwatch sw = new Stopwatch(); 
sw.Start(); 
var re = new Regex(@"(\d\d)/(\d\d)/(\d\d\d\d) (\d\d):(\d\d):(\d\d)", RegexOptions.Compiled); 
for (int i = 0; i < 100000; i++) 
{ 
    //var m = re.Match("08/01/2012 23:10:12"); 
    DateTime.Parse("08/01/2012 23:10:12", CultureInfo.CreateSpecificCulture("en-US")); 
} 
sw.Stop(); 
Console.WriteLine(sw.ElapsedMilliseconds); 

Edit: Mark è a destra, spostando la CultureInfo.CreateSpecificCulture("en-US") fuori del ciclo aiutato. La ragione per cui non l'ho fatto prima è che ho fatto il profilo questo codice con VS Profiler ed ha mostrato seguente risultato:

enter image description here

risposta

23

Non è un test giusto.

  1. La chiamata a CultureInfo.CreateSpecificCulture("en-US") è la parte lenta. Spostalo all'esterno del ciclo, memorizza il risultato e riutilizzalo.

  2. L'espressione regolare gestisce solo un formato specifico, ma DateTime.Parse può gestire molti formati di input diversi. Deve decidere quale tra i molti formati che comprende è quello corretto da usare. Se si conosce in anticipo qual è il formato, utilizzare DateTime.ParseExact anziché DateTime.Parse.

Il codice fisso è il seguente:

CultureInfo ci = CultureInfo.CreateSpecificCulture("en-US"); 
for (int i = 0; i < 100000; i++) 
{ 
    DateTime.ParseExact("08/01/2012 23:10:12", "MM/dd/yyyy HH:mm:ss", ci); 
} 

Con queste due modifiche, ottengo che la DateTime.ParseExact e l'approccio espressione regolare sono quasi la stessa cosa.

E la tua espressione regolare accetta alcuni giorni non validi, come ad esempio 00/00/0000 99:99:99. Se lo aggiusti in modo che accetti solo scadenze valide, sarebbe più lento.

+1

Oooh, mi sento così stupido, in realtà spostare 'CreateSpecificCulture' dal ciclo di prestazioni fisse. La ragione per cui non l'ho fatto prima, perché ho usato VS Profiler e ha mostrato che il problema è nel 'Parse', vedi screenshot in edit. – Andrey

+0

Sono d'accordo, ovviamente, che usare Regex è una sorta di imbroglio qui, ma ho preso in considerazione il passaggio ad esso perché ero sicuro al 100% che i dati di input fossero validi e che le prestazioni fossero più importanti. – Andrey