2013-04-03 6 views
14

Ich sah nur this upvoted commentWie wichtig ist es, eine Variable für DateTime.Today zu verwenden, wenn es um die Leistung geht? ersten

IIRC DateTime.Today ist ein ziemlich teuer Anruf, so dass Sie besser den Wert in einer Variablen speichern.

Es als Antwort auf einen Beitrag war, die den Code enthalten:

var first = 
    new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1); 
var last = 
    new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddDays(-1); 

Wenn ich die Leistung zu verbessern suchen, wie wichtig es ist DateTime.Today in einer Variablen zu speichern, anstatt es mehrmals zu nennen? Und ungefähr wie viele Verwendungen von DateTime.Today würde es rechtfertigen, eine Variable dafür zu erstellen?

Bearbeiten: Ich weiß, dass ich mein Programm testen sollte, um zu sehen, ob es Leistungsprobleme gibt, bevor Sie sich über etwas so Triviales wie dieses Sorgen machen. Nehmen Sie für diese Frage an, dass ich dies bereits getan habe und festgestellt habe, dass zusätzliche Optimierung erforderlich ist.

+0

Persönlich würde ich nur eine Variable nehmen, wenn ich wollte, dass der Today-Wert für alle Verwendungen gleich ist. Ansonsten würde ich für Lesbarkeit kodieren und das Leistungsproblem vergessen, bis es ein Hot Spot wird. Natürlich ist die offensichtliche Antwort, wenn die Leistung vorrangig ist, eine Variable zu nehmen, wann immer Sie sie 2 oder öfter benutzen. Wie oft, bevor es zu einem Problem wird, ist völlig subjektiv, aber ich würde vermuten, dass es eine Menge Anrufe braucht, bevor es zu einem Problem kommt. –

+2

Ich denke, du solltest ein Programm schreiben, um es zu testen und die Ergebnisse zu posten! –

+2

Randnotiz: das Hauptproblem mit diesem Code ist es * nicht korrekt * - stellen Sie sich vor, was einmal pro Tag/Jahr passieren wird, wenn 2 Aufrufe an 'Today' unterschiedliche Tage erreichen. Es zeigt auch, dass "Heute"/"Jetzt" nicht testbar sind, da der Schreibeinheit-Test für das "neue Jahr" weniger als trivial ist - daher wäre es viel besser, diesen Aufruf zu abstrahieren, selbst bei einigen Leistungskosten und Testergebnissen. –

Antwort

5

Benchmark (auf meiner Maschine, die Stoppuhr-Klasse):

10,000 DateTime.Today calls and assignment to local variable: 0.0125781 seconds. 

10,000 Assignment only operations: 0.0001062 seconds. 

Code:

var s = new Stopwatch(); 
DateTime date = DateTime.Today; 
DateTime date2 = DateTime.Today; 
s.Start(); 
for (int i=0; i<10000; i++) 
    date = DateTime.Today; 
s.Stop(); 
Debug.Print(s.Elapsed.ToString()); 

s.Reset(); 
s.Start(); 
for (int i=0; i<10000; i++) 
    date2 = date; 
s.Stop(); 
Debug.Print(s.Elapsed.ToString()); 
+0

Ich habe gerade 100.000 und es dauerte etwa 37-38 ms – Cemafor

+0

@Cemafor: Ich poste meinen Code. Es ist auf einer Quad-Core-Dell Precision-Workstation, etwa 2 Jahre alt. –

+0

Die Schlussfolgerung, die ich aus Ihrer Antwort gezogen habe, ist die Annahme, dass der Anspruch von "DateTime.Today", ein "teurer" Anruf zu sein, nicht wirklich wahr ist (zumindest mit der heutigen Technologie). Es ist ein teurer Anruf als das Lesen von einer Variablen, aber der Anruf selbst ist nicht wirklich teuer und ich sollte mich nicht wirklich darum kümmern, es sei denn, ich versuche, Ihren Code zu optimieren. Danke :) – Rachel

9

wie wichtig ist es DateTime.Today in einer Variablen

die beste Antwort zu speichern, dass der Benchmark auf der Hardware ist, dass Sie Ihren Code erwarten auf zu laufen. Es sei denn, Sie nennen es in einer extrem engen Schleife, ich bezweifle, dass es ein Problem sein wird.

Ein besserer Grund, es in einer Variablen zu speichern, ist, dass Sie zwischen den beiden Aufrufen von einem Tag auf den anderen wechseln könnten.

UPDATE

eine Größenordnung bereitzustellen, geteilt @RichardBrown einen Link in seiner Antwort darauf hinweist, dass die Kosten für DateTime.Today wurden in der Größenordnung von einigen hundert Nanosekunden sein wird getestet (auf der speziellen Hardware für diesen Test verwendet).

+0

+1 speziell für "roll over" - 'Today' /' Now' im gesamten Code aufgerufen wird leicht zu interessanten Problemen führen, wenn mehrere Male in derselben Berechnung/Bedingung aufgerufen ... Und man kann solchen Code nicht testen - so " Leistungsverbesserungen "aufgrund der Zwischenspeicherung des Ergebnisses werden wahrscheinlich erreicht, indem die Korrektheit vollständig ignoriert wird. –

+0

Danke, dass Sie einen guten Grund angegeben haben, eine Variable anstelle von 'DateTime.Today' zu verwenden. Ich frage jedoch speziell, ob' DateTime.Today' eine teure Operation ist, um meinen Code zu optimieren und Ihre Antwort auf " Ich bezweifle es "ist nicht wirklich, was ich gesucht habe :) – Rachel

+0

Wenn Sie wirklich an Mikro-Optimierung interessiert sind, finden Sie im Blog-Post in @ RichardBrowns Antwort, dass ich in meiner Antwort verweisen. –

3

Ich lehne die Prämisse ab, dass DateTime.Today ein teurer Anruf ist. Sie sollten es in einer Variablen speichern, wenn es wichtig ist, dass es sich im Laufe der Zeit nicht ändert. Wenn dieser Code gegen Mitternacht des Monatsendes läuft, könnten Sie ... Probleme haben. Aus der Sicht der Performance I hoch Zweifel, dass dies ein Problem sein würde.

In jedem Fall wäre es eine Mikro-Optimierung. Wie bei allen Leistungsproblemen, wenn Ihr Programm zu langsam ist, sollten Sie es profilieren und nach Abschnitten suchen, die ziemlich viel Zeit in Anspruch nehmen und sich darauf konzentrieren, diese zu optimieren. Wenn es dazu kommt, dass diese eine Codezeile viel Zeit in Anspruch nimmt, dann überlegen Sie, sie zu ändern. Bis dahin, refactor nur für die Richtigkeit oder Lesbarkeit, nicht die Leistung.

0

Wichtiger als die Frage der Leistung ist die Lesbarkeit und Wartbarkeit des Codes.

es sei denn, Sie nicht Performance-Probleme haben ich die Regel folgen würde „achten Sie auf Leistungsverbesserungen“

Vielleicht, wenn Sie eine Schleife als eine Variable mit „heute“ angemessen benannt werden kann, aber wieder, so lange es gibt keine Leistung ausgegeben, ich würde mich auf die anderen Bedenken konzentrieren

2

Für harte Zahlen auf die Leistung von DateTime lesen this blog post. Wie die vorherigen Antworten zeigen, ist es wichtig, dass Sie sich bei der Leistungsbestimmung auf Ihre spezielle Konfiguration und Ihre Bedürfnisse konzentrieren.

1

Ich würde vermuten, dass es ein Problem ist, wenn Sie den Code in einer Schleife aufrufen. Aber der beste Weg, um herauszufinden, ist es, Zeit zu nehmen und selbst zu sehen, wie lange es dauert.

var sw = new Stopwatch(); 
sw.Start(); 
today = DateTime.Today(); 
sw.Stop(); 
var ts = stopWatch.Elapsed; 

MSDN Stopwatch reference

+0

Die Zeit, die für einen einzelnen Anruf benötigt wird, wie für etwas, das so schnell ist, ist bedeutungslos. Sie müssen * viele * Anrufe im Durchschnitt die verbrachte Zeit machen. – Servy

1

Der wahre Grund DateTime.Today zu extrahieren als Variable ist verhindern mögliche Fehler, die wird erscheinen wegen Murphy's law, würde aber nie ..

Idee isoliert und fixiert werden, dass zwischen dem ersten und den zweiten Einsatz von Today tatsächlichem Datum geändert werden kann, so dass man bekommen kann, zum Beispiel, Vorjahr und neuen Monat hier:

var first = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1); 

, die zum Beispiel zur Folge haben können, in (January 2013) - 1 month statt (December 2013) - 1 month.

Wahrscheinlicher und mehr böses Problem wird sein, wenn Sie Datumswechsel zwischen first und last Zuordnung erhalten:

var first = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1); 
var last = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddDays(-1); 

, die ein Jahr mehr Zeit zur Folge haben werden .. Je nach Ihrer Logik kann es wirklich führen teurer Verlust.

Verwandte Themen