Frage

public Int64 ReturnDifferenceA()
{
  User[] arrayList;
  Int64 firstTicks;
  IList<User> userList;
  Int64 secondTicks;
  System.Diagnostics.Stopwatch watch;

  userList = Enumerable
              .Range(0, 1000)
              .Select(currentItem => new User()).ToList();

  arrayList = userList.ToArray();

  watch = new Stopwatch();
  watch.Start();

  for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
  {
     DoThings(arrayList[loopCounter]);
  }

  watch.Stop();
  firstTicks = watch.ElapsedTicks;

  watch.Reset();
  watch.Start();
  for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
  {
     DoThings(arrayList[loopCounter]);
  }
  watch.Stop();
  secondTicks = watch.ElapsedTicks;

  return firstTicks - secondTicks;
}

Wie Sie sehen können, ist dies ganz einfach. Erstellen Sie eine Liste der Benutzer, zwingen zu einem Array, starten Sie eine Uhr, Schleife die Liste durch und eine Methode aufrufen, Stoppuhr. Wiederholen. Beenden, indem die Differenz aus dem ersten Lauf der Rückkehr und die zweite.

Jetzt mit diesen Ich rufe:

differenceList = Enumerable
                 .Range(0, 50)
                 .Select(currentItem => ReturnDifferenceA()).ToList();
average = differenceList.Average();

differenceListA = Enumerable
                  .Range(0, 50)
                  .Select(currentItem => ReturnDifferenceA()).ToList();
averageA = differenceListA.Average();

differenceListB = Enumerable
                  .Range(0, 50)
                  .Select(currentItem => ReturnDifferenceA()).ToList();
averageB = differenceListB.Average();

Jetzt ist der Spaß daran ist, dass alle Mittelwert durch eine relativ große Menge positiv sind, im Bereich von 150k bis 300k Zecken.

Was ich nicht bekommen, ist, dass ich durch die gleiche Liste werde, die gleiche Art und Weise, mit der gleichen Methode und doch gibt es solch einen Unterschied. Gibt es irgendeine Art von Caching los?

Eine weitere interessante Sache ist, dass, wenn ich durch die Liste vor dem ersten Stoppuhr Abschnitt durchlaufen, sind die Mittelwerte um 5k oder so.

War es hilfreich?

Lösung

durch die Art und Weise, mit IEnumerable.Count () auf einem Array ist mehrere hundert Mal langsamer als Array.length ... Obwohl dies nicht die Frage gar nicht beantworten.

Andere Tipps

Sie sind in einer Hochsprache mit einer Laufzeitumgebung ausgeführt, die eine Menge von Caching und Performance-Optimierungen tut, ist dies üblich. Manchmal ist es Erwärmung genannt die virtuelle Maschine, oder den Server aufwärmen (wenn es sich um eine Produktionsanwendung ist).

Wenn etwas geht immer wieder zu tun, dann werden Sie häufig das erste Mal bemerken, hat eine größere gemessene Laufzeit und der Rest sollte auf einen kleineren Betrag einpendeln.

Ich tue dies in MATLAB-Code und sehe, dass das erste Mal, dass ich eine Benchmark-Schleife laufen, es 5 Sekunden dauert, und nachfolgende Zeiten nehmen ein Fünftel einer Sekunde. Es ist ein großer Unterschied, weil es eine interpretierte Sprache, die eine Form der Zusammenstellung erforderlich ist, aber in Wirklichkeit ist es nicht Ihre Leistung auswirken, weil die große Mehrheit ‚zweites Mal in jeder einzelnen Produktionsanwendung sein.

Es ist durchaus möglich, dass DoThings () ist nicht JIT-kompilierte nativen Code bis zum ersten Mal aufgerufen wird.

Da .NET, wie die Java-Plattform, ist eine JIT-Umgebung. All hoher .NET-Code wird an Microsoft Intermediate Language-Bytecode kompiliert.

Ihr Programm ausführen zu können, muss diese Bytecode nativen Maschinencode kompiliert / übersetzt werden. Allerdings kompilierte .NET programmiert Dateien werden in nativen Maschinencode, sondern in der Zwischen virtuellen Maschine Bytecode nicht gespeichert.

Der erste Lauf wird JIT kompiliert, so dauerte es mehr Zeit. Die nachfolgenden Ausführungen nicht mehr benötigen, JIT kompiliert werden, aber der native Code wird aus der JIT-Cache gezogen, so sollte es schneller sein.

Haben Sie halten Ihre Anwendung, ohne auf den folgenden Durchläufen beendet wird? Dann ist der zweite Grund zu VM auch fällig. (VM: 1 = virtuelle Maschine; VM: 2 = virtuelle Speicher). Alle modernen verallgemeinerte Betriebssysteme laufen, ihre Prozesse auf dem virtuellen Speicher, die eine Karte von Realspeicher ist, dem Betriebssystem die Fähigkeit, ermöglichen die Verwendung von Systemressourcen zu verwalten und zu optimieren. Weniger verwendete Prozesse in der Disk-Cache werden häufig gefegt andere Prozesse optimale Nutzung der Ressourcen haben zu lassen.

Ihr Prozess war nicht im virtuellen Speicher das erste Mal, so hat es den Overhead erleiden in dem Speicher gefegt. Da anschließend Ihr Prozess unter der zuletzt verwendeten Top-Liste (aka am unteren Rande der zuletzt verwendeten Liste) war, wurde er nicht in der Disk-Cache gefegt noch.

Auch Ressourcen werden durch das Betriebssystem für Ihren Prozess ausgeteilt nach Bedarf. Also für die erste Runde, hatte Ihr Prozess des Drückens den Umschlag Streit mit dem Betriebssystem durch die Schmerzen zu gehen, um die Ressourcengrenzen zu erweitern.

Eine virtuelle Maschine ermöglicht .NET und Java zu abstrahieren die meisten Programmierfunktionen in eine maschinenunabhängige Schicht, Absonderungs und damit eine kleinere Chaos für die maschinenabhängigen Software-Ingenieure verlassen, zu beschäftigen. Auch wenn Microsoft Windows läuft auf ziemlich einheitliche x86 Nachkommen Hardware gibt es genügend Unterschiede mit verschiedenen OS-Versionen und CPU-Modellen eine abstrahierte virtuelle Maschine, um zu gewährleisten, eine konsistente Sicht zu geben .NET-Programmierer und Anwender.

Sie sagen, Sie nicht bekommen, dass es 3 mal tun, die 2. und 3. Mal relativ nah sind. Es scheint mir, dass es nur das erste Mal durch die Schleife, die Dinge langsam sind.

Ich würde vermuten, dass die Funktion, die Sie rufen nicht Just-In-Zeitüberschreitung bis zum ersten Lauf ist. Was können Sie versuchen, es einmal läuft, stoppen sie dann und führen Sie es erneut. Ohne Code-Änderungen, die Just-In-Time kompiliert aus dem vorherigen Lauf noch in Ordnung sein sollte, und alle verbleibenden Optimierungen Sie sehen, sind die ist Caching-Effekte bei der Arbeit.

Beiseite lassen die Frage der Erwärmung der VM oder Maschine, von Caching von JIT-Optimierungen, für einen Moment auf: was sonst ist Ihr Computer? Sind irgendwelche der 3e42 Systemdienste und Taskleiste thingies greifen einige CPU? Vielleicht entschied Ihr Steam-Client nach Updates zu suchen, oder IE brauchte etwas fürchterlich wichtig, oder Ihr Antivirenprogramm war im Weg zu tun?

Ihr Test ist nur so nützlich wie der Grad, in dem man es von allen anderen Software isolieren kann auf Ihrem System ausgeführt wird. Schalten Sie jedes Stück Software, die Sie möglicherweise können, bevor Sie einen Lauf zu messen.

Aber was weiß ich? -. Vielleicht Ihre Messmethode wird von der .net (oder was auch immer) Laufzeit zu verwalten und macht nur Laufzeit ‚virtuelle Zyklen‘

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top