it-swarm.com.de

Leistungsunterschiede zwischen Debug- und Release-Builds

Ich muss zugeben, dass ich mich normalerweise nicht darum gekümmert habe, zwischen den Konfigurationen Debug und Release in meinem Programm zu wechseln, und ich habe mich normalerweise für = entschieden Debug Konfiguration, auch wenn die Programme tatsächlich beim Kunden bereitgestellt werden.

Soweit ich weiß, besteht der einzige Unterschied zwischen diesen Konfigurationen, wenn Sie sie nicht manuell ändern, darin, dass Debug die Konstante DEBUG definiert hat. und Release haben den Code optimieren überprüft.

Meine Fragen sind also zweifach:

  1. Gibt es große Leistungsunterschiede zwischen diesen beiden Konfigurationen? Gibt es einen bestimmten Codetyp, der zu großen Leistungsunterschieden führt, oder ist dieser eigentlich nicht so wichtig?

  2. Gibt es eine Art von Code, der in der Debug Konfiguration einwandfrei funktioniert und in der Release Konfiguration möglicherweise fehlschlägt, oder können Sie sicher sein, dass dieser Code getestet wurde und Das Funktionieren unter der Debug Konfiguration funktioniert auch unter der Release Konfiguration.

273

Der C # -Compiler selbst ändert die ausgegebene IL im Release-Build nicht wesentlich. Bemerkenswert ist, dass die NOP-Opcodes, mit denen Sie einen Haltepunkt für eine geschweifte Klammer festlegen können, nicht mehr ausgegeben werden. Der große ist der Optimierer, der in den JIT-Compiler integriert ist. Ich weiß, es macht die folgenden Optimierungen:

  • Methode Inlining. Ein Methodenaufruf wird durch das Einfügen des Codes der Methode ersetzt. Dies ist eine große Sache, es macht Eigenschaft Accessors im Wesentlichen kostenlos.

  • CPU-Registerzuordnung. Lokale Variablen und Methodenargumente können in einem CPU-Register gespeichert bleiben, ohne jemals (oder seltener) in den Stack-Frame zurückgespeichert zu werden. Dies ist eine große Sache, die das Debuggen von optimiertem Code so schwierig macht. Und dem flüchtigen Schlüsselwort eine Bedeutung geben.

  • Eliminierung der Überprüfung des Array-Index. Eine wichtige Optimierung beim Arbeiten mit Arrays (alle .NET-Auflistungsklassen verwenden intern ein Array). Wenn der JIT-Compiler überprüfen kann, dass eine Schleife ein Array niemals außerhalb der Grenzen indiziert, wird die Indexprüfung aufgehoben. Großes.

  • Abrollen der Schleife. Schleifen mit kleinen Körpern werden verbessert, indem der Code bis zu viermal im Körper wiederholt und weniger geschleift wird. Reduziert die Zweigstellenkosten und verbessert die superskalaren Ausführungsoptionen des Prozessors.

  • Beseitigung toter Codes. Eine Aussage wie if (false) {/.../} wird vollständig eliminiert. Dies kann durch ständiges Falten und Inlinen geschehen. In anderen Fällen kann der JIT-Compiler feststellen, dass der Code keine möglichen Nebenwirkungen hat. Diese Optimierung macht das Erstellen von Profilen so schwierig.

  • Code-Heben. Code in einer Schleife, der nicht von der Schleife betroffen ist, kann aus der Schleife verschoben werden. Der Optimierer eines C-Compilers wird viel mehr Zeit damit verbringen, Möglichkeiten zum Heben zu finden. Es ist jedoch eine teure Optimierung aufgrund der erforderlichen Datenflussanalyse, und der Jitter kann sich die Zeit nicht leisten, sodass nur offensichtliche Fälle behoben werden. Erzwingen, dass .NET-Programmierer besseren Quellcode schreiben und sich selbst weiterentwickeln.

  • Gemeinsame Eliminierung von Unterausdrücken. x = y + 4; z = y + 4; wird z = x; Ziemlich häufig in Anweisungen wie dest [ix + 1] = src [ix + 1]; Zur besseren Lesbarkeit geschrieben, ohne eine Hilfsvariable einzufügen. Die Lesbarkeit muss nicht beeinträchtigt werden.

  • Ständiges Falten. x = 1 + 2; wird x = 3; Dieses einfache Beispiel wird vom Compiler frühzeitig erkannt, geschieht jedoch zur JIT-Zeit, wenn andere Optimierungen dies ermöglichen.

  • Kopieren Sie die Weitergabe. x = a; y = x; wird y = a; Dies hilft dem Registerzuordner, bessere Entscheidungen zu treffen. Es ist eine große Sache im x86-Jitter, weil es nur wenige Register gibt, mit denen gearbeitet werden kann. Die Auswahl der richtigen ist entscheidend für die Perfektion.

Dies sind sehr wichtige Optimierungen, die einen großen Unterschied machen können, wenn Sie beispielsweise den Debug-Build Ihrer App profilieren und mit dem Release-Build vergleichen. Das ist jedoch nur dann wirklich wichtig, wenn sich der Code auf Ihrem kritischen Pfad befindet und 5 bis 10% des von Ihnen geschriebenen Codes tatsächlich die Leistung Ihres Programms beeinflussen. Das JIT-Optimierungsprogramm ist nicht intelligent genug, um im Voraus zu wissen, worauf es ankommt. Es kann nur die Wählscheibe "auf elf stellen" für den gesamten Code verwenden.

Das effektive Ergebnis dieser Optimierungen für die Ausführungszeit Ihres Programms wird häufig durch Code beeinflusst, der an anderer Stelle ausgeführt wird. Lesen einer Datei, Ausführen einer Datenbankabfrage usw. Die Arbeit des JIT-Optimierers wird vollständig unsichtbar. Es macht aber nichts aus :)

Der JIT-Optimierer ist ein ziemlich zuverlässiger Code, vor allem, weil er millionenfach getestet wurde. In der Release-Build-Version Ihres Programms treten äußerst selten Probleme auf. Es kommt jedoch vor. Sowohl der x64- als auch der x86-Jitter hatten Probleme mit Strukturen. Der x86-Jitter hat Probleme mit der Gleitkommakonsistenz und führt zu geringfügig unterschiedlichen Ergebnissen, wenn die Zwischenstufen einer Gleitkommaberechnung mit einer Genauigkeit von 80 Bit in einem FPU-Register gespeichert werden, anstatt beim Löschen in den Speicher abgeschnitten zu werden.

504
Hans Passant
  1. Ja, es gibt viele Leistungsunterschiede, die sich wirklich auf Ihren gesamten Code auswirken. Debug führt sehr wenig Leistungsoptimierung und Release-Modus sehr viel aus;

  2. Nur Code, der sich auf die Konstante DEBUG stützt, kann bei einem Release-Build eine andere Leistung erbringen. Außerdem sollten Sie keine Probleme sehen.

Ein Beispiel für Framework-Code, der von der Konstante DEBUG abhängt, ist die Methode Debug.Assert(), für die das Attribut [Conditional("DEBUG)"] definiert ist. Dies bedeutet, dass dies auch von der Konstante DEBUG abhängt und diese nicht im Release-Build enthalten ist.

23

Dies hängt stark von der Art Ihrer Anwendung ab. Wenn Ihre Anwendung UI-lastig ist, werden Sie wahrscheinlich keinen Unterschied bemerken, da die langsamste Komponente, die an einen modernen Computer angeschlossen ist, der Benutzer ist. Wenn Sie einige Benutzeroberflächenanimationen verwenden, möchten Sie möglicherweise testen, ob Sie beim Ausführen des DEBUG-Builds eine spürbare Verzögerung feststellen können.

Wenn Sie jedoch über viele rechenintensive Berechnungen verfügen, werden Sie Unterschiede feststellen (können bis zu 40% betragen, wie bei @Pieter angegeben, obwohl dies von der Art der Berechnungen abhängt).

Es ist im Grunde ein Design-Kompromiss. Wenn Sie ein Release unter DEBUG Build veröffentlichen, können Sie bei Problemen der Benutzer einen aussagekräftigeren Traceback erhalten und eine wesentlich flexiblere Diagnose durchführen. Durch die Veröffentlichung im DEBUG-Build vermeiden Sie auch, dass der Optimierer obskure Heisenbugs erzeugt.

12
Lie Ryan
  • Ich habe die Erfahrung gemacht, dass mittelgroße oder größere Anwendungen in einem Release-Build spürbar reaktionsschneller sind. Probieren Sie es mit Ihrer Anwendung aus und sehen Sie, wie es sich anfühlt.

  • Eine Sache, die Sie bei Release-Builds beißen kann, ist, dass Debug-Build-Code manchmal Race-Bedingungen und andere Threading-bezogene Fehler unterdrücken kann. Optimierter Code kann zu einer Neuordnung der Befehle führen und eine schnellere Ausführung kann bestimmte Rennbedingungen verschlechtern.

11
Dan Bryant

Sie sollten niemals ein .NET-Debug-Build für die Produktion freigeben. Es kann hässlichen Code enthalten, um Edit-and-Continue zu unterstützen, oder wer weiß was anderes. Soweit ich weiß, geschieht dies nur in VB nicht in C # (Anmerkung: der ursprüngliche Beitrag ist mit C # markiert, aber es sollte immer noch Grund zum Anhalten geben Microsoft ist der Ansicht, dass sie mit einem Debug-Build arbeiten dürfen. Tatsächlich verliert vor .NET 4.0 VB} Code proportional zur Anzahl der Instanzen von Objekten mit Ereignissen, die Sie zur Unterstützung von Edit-and-Continue erstellen, Speicher Fixiert werden per https://connect.Microsoft.com/VisualStudio/feedback/details/481671/vb-classes-with-events-are-not-garbage-collected-when-debugging , der generiert wird Code sieht fies aus, indem er WeakReference Objekte erstellt und sie einer statischen Liste hinzufügt, während eine Sperre besitzt) Ich möchte auf keinen Fall diese Art von Debugging-Unterstützung in einer Produktionsumgebung !

9
Jason Kresowaty

Nach meiner Erfahrung sind die dunklen "Release Bugs" das Schlimmste, was den Release-Modus verlassen hat. Da die IL (Intermediate Language) im Release-Modus optimiert ist, besteht die Möglichkeit von Fehlern, die im Debug-Modus nicht aufgetreten wären. Es gibt andere SO Fragen zu diesem Problem: Häufige Gründe für Fehler in der Release-Version, die im Debug-Modus nicht vorhanden sind

Dies ist mir ein- oder zweimal passiert, wenn eine einfache Konsolen-App im Debug-Modus einwandfrei funktioniert, aber bei genau derselben Eingabe im Release-Modus ein Fehler auftritt. Diese Bugs sind EXTREM schwierig zu debuggen (ironischerweise per Definition des Release-Modus).

5
Roly

Ich würde sagen, dass 1) weitgehend von Ihrer Implementierung abhängt. Normalerweise ist der Unterschied nicht so groß. Ich habe viele Messungen durchgeführt und oft konnte ich keinen Unterschied feststellen. Wenn Sie nicht verwalteten Code, viele große Arrays und ähnliches verwenden, ist der Leistungsunterschied etwas größer, aber nicht anders (wie in C++). 2) In der Regel werden im Release-Code weniger Fehler angezeigt (höhere Toleranz), daher sollte ein Switch problemlos funktionieren.

3
testalino
    **Debug Mode:**
    Developer use debug mode for debugging the web application on live/local server. Debug mode allow developers to break the execution of program using interrupt 3 and step through the code. Debug mode has below features:
   1) Less optimized code
   2) Some additional instructions are added to enable the developer to set a breakpoint on every source code line.
   3) More memory is used by the source code at runtime.
   4) Scripts & images downloaded by webresource.axd are not cached.
   5) It has big size, and runs slower.

    **Release Mode:**
    Developer use release mode for final deployment of source code on live server. Release mode dlls contain optimized code and it is for customers. Release mode has below features:
    More optimized code
    Some additional instructions are removed and developer can’t set a breakpoint on every source code line.
   1) Less memory is used by the source code at runtime.
   2) Scripts & images downloaded by webresource.axd are cached.
   3) It has small size, and runs fast.
   4) Scripts & images downloaded by webresource.axd are cached.
   5) It has small size, and runs fast.
0
Nandha kumar