9 Stimmen

Gibt es einen Overhead bei der Verwendung von anonymen Methoden?

Ich würde gerne wissen, ob beim Erstellen eines Background-Arbeiter durch die Verwendung anonymer Methoden ein Overhead entsteht.

zum Beispiel:

public void SomeMethod()
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (sender, e) =>
    {
        //große Menge an Code
    }

    worker.RunWorkerAsync();
}

Wäre das obige Beispiel besser oder schlechter als das Definieren des //großen Menge an Code in einer separaten Methode?

Entsteht ein Overhead, wenn die Hintergrundarbeitermethode inline definiert wird, insbesondere wenn SomeMethod() oft aufgerufen wird?

6voto

Guffa Punkte 663241

Es gibt einen kleinen Unterschied darin, wie benannte Methoden und anonyme Methoden behandelt werden, wenn Sie einen Delegaten aus ihnen erstellen.

Delegaten für anonyme Methoden werden zwischengespeichert, daher gibt es einen kleinen Overhead, um zu überprüfen, ob der Delegat bereits im Cache vorhanden ist. Andererseits, wenn Sie die Methode mehr als einmal ausführen, wird sie den zwischengespeicherten Delegaten wiederverwenden, anstatt einen neuen zu erstellen.

Delegaten für benannte Methoden werden nicht zwischengespeichert, daher wird er jedes Mal erstellt.

Ansonsten gibt es keinen Unterschied. Die anonyme Methode wird zur Compile-Zeit erstellt und existiert im Code genauso wie eine reguläre Methode, nur mit einem Namen, den nur der Compiler kennt.

2voto

svick Punkte 224493

Zunächst sollten Sie wahrscheinlich keinen großen Code in einer anonymen Methode platzieren. Es wäre lesbarer, wenn Sie dafür eine separate Methode erstellen würden, oder noch besser, mehrere Methoden.

Was den generierten IL-Code betrifft: Wenn die Lambda keine Variablen schließt, ist der generierte IL-Code derselbe wie wenn Sie den Code in eine normale benannte Methode setzen (außer dass die generierte Methode einen unaussprechlichen Namen hat).

Andererseits, wenn Sie über einige Variablen schließen, erstellt der Compiler eine Closure-Klasse, um diese Variable in einem Feld zu halten. Und der Zugriff auf Felder ist leicht teurer als der Zugriff auf lokale Variablen.

Zusammenfassend: Wenn Sie über einige Variablen schließen, gibt es einen kleinen Overhead (einschließlich mehr Objekte, die vom Garbage Collector gesammelt werden müssen). In den meisten Situationen ist das unwichtig und sich darüber Gedanken zu machen wäre vorzeitige Optimierung. Aber wenn Sie glauben, dass es wichtig ist, sollten Sie den Code profilieren.

1voto

Rich O'Kelly Punkte 40414

Immer wenn eine anonyme Methode (einschließlich Lambdas) über Variablen schließt, erstellt der Compiler eine Klasse, um diese Variablen für Sie zu halten. Immer wenn der Delegat erstellt wird, geschieht dies auch mit einer neuen Instanz dieser Klasse. Dies fügt offensichtlich zusätzliche Arbeit für die Laufzeit hinzu, ist jedoch in den meisten Situationen vernachlässigbar.

0voto

Moonshield Punkte 905

Ich habe das neulich getestet (über die Verwendung der StopWatch-Klasse). Soweit ich das beurteilen konnte, gab es keinen spürbaren Unterschied in der Leistung zwischen dem direkten Aufruf einer Methode...

SomeMethod();

...oder über eine anonyme Methode...

() => SomeMethod();

0voto

Matthias Punkte 11592

Es betrifft hauptsächlich die Lesbarkeit - große Mengen Code an einem Ort sind fast nie gut ;-)

In terms of performance see Wann ist Optimierung voreilig?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X