Was ist eine verzögerte Initialisierung von Objekten? Wie machst du das und was sind die Vorteile?
83
Lazy Initialization ist eine Leistungsoptimierung, bei der Sie die (möglicherweise teure) Objekterstellung verschieben, bis Sie sie tatsächlich benötigen.
Ein gutes Beispiel ist, keine Datenbankverbindung im Voraus zu erstellen, sondern nur kurz bevor Sie Daten aus der Datenbank abrufen müssen.
Der Hauptgrund dafür ist, dass Sie (häufig) vermeiden können, das Objekt vollständig zu erstellen, wenn Sie es nie benötigen.
Lazy
ist in der folgenden SO-Frage aufgeführt: stackoverflow.com/a/15894928/4404962 Dieser Vorschlag löste genau das, was wir lösen mussten -Lazy
alsWie andere bereits erwähnt haben, verzögert die verzögerte Initialisierung die Initialisierung, bis eine Komponente oder ein Objekt verwendet wird. Sie können die verzögerte Initialisierung als Laufzeitanwendung des YAGNI-Prinzips anzeigen - "
You ain't gonna need it
"Die Vorteile einer verzögerten Initialisierung aus Anwendungssicht bestehen darin, dass Benutzer die Initialisierungszeit nicht für Funktionen bezahlen müssen, die sie nicht verwenden. Angenommen, Sie würden jede Komponente Ihrer Anwendung im Voraus initialisieren. Dies kann zu einer möglicherweise langen Startzeit führen. Benutzer müssen Dutzende von Sekunden oder Minuten warten, bis Ihre Anwendung einsatzbereit ist. Sie warten auf die Initialisierung von Funktionen, die sie möglicherweise nie oder nicht sofort nutzen.
Wenn Sie die Initialisierung dieser Komponenten bis zur Nutzungsdauer verschieben, wird Ihre Anwendung stattdessen viel schneller gestartet. Der Benutzer muss weiterhin die Startkosten bezahlen, wenn er andere Komponenten verwendet. Diese Kosten werden jedoch über die Programmlaufzeit amortisiert und nicht auf den Anfang reduziert, und der Benutzer kann die Initialisierungszeit dieser Objekte mit den Funktionen verknüpfen, die sie sind mit.
quelle
Lazy Initialization ist das Konzept, die Objekterstellung zu verschieben, bis das Objekt tatsächlich zum ersten Mal verwendet wird. Bei sachgemäßer Verwendung kann dies zu erheblichen Leistungssteigerungen führen.
Persönlich habe ich Lazy Initialization verwendet, um mein eigenes handgerolltes ORM in .NET 2.0 zu erstellen. Beim Laden meiner Sammlungen aus der Datenbank wurden die tatsächlichen Elemente in der Sammlung verzögert initialisiert. Dies bedeutete, dass die Sammlungen schnell erstellt wurden, aber jedes Objekt nur geladen wurde, wenn ich es benötigte.
Wenn Sie mit dem Singleton-Muster vertraut sind, haben Sie wahrscheinlich auch eine verzögerte Initialisierung in Aktion gesehen.
public class SomeClassSingleton { private static SomeClass _instance = null; private SomeClassSingleton() { } public static SomeClass GetInstance() { if(_instance == null) _instance = new SomeClassSingleton(); return _instance; } }
In diesem Fall wird die Instanz von SomeClass erst initialisiert, wenn sie vom SomeClassSingleton-Consumer zum ersten Mal benötigt wird.
quelle
Im Allgemeinen bedeutet "verzögerte Auswertung", die Verarbeitung auf etwas zu verschieben, bis Sie es tatsächlich benötigen. Die Hauptidee ist, dass Sie manchmal kostspielige Vorgänge vermeiden können, wenn Sie feststellen, dass Sie sie nicht benötigen oder wenn sich der Wert ändern würde, bevor Sie ihn verwenden.
Ein einfaches Beispiel hierfür ist System.Exception.StackTrace. Dies ist eine Zeichenfolgeeigenschaft für eine Ausnahme, die jedoch erst erstellt wird, wenn Sie darauf zugreifen. Intern macht es so etwas wie:
String StackTrace{ get{ if(_stackTrace==null){ _stackTrace = buildStackTrace(); } return _stackTrace; } }
Dies erspart Ihnen den Aufwand, buildStackTrace tatsächlich aufzurufen, bis jemand sehen möchte, was es ist.
Eigenschaften sind eine Möglichkeit, diese Art von Verhalten einfach bereitzustellen.
quelle
Hier können Sie über Lazy Initialization mit Beispielcode lesen .
quelle
Eine verzögerte Initialisierung eines Objekts bedeutet, dass seine Erstellung verschoben wird, bis es zum ersten Mal verwendet wird. (In diesem Thema sind die Begriffe "verzögerte Initialisierung" und "verzögerte Instanziierung" synonym.) Die verzögerte Initialisierung wird hauptsächlich verwendet, um die Leistung zu verbessern, verschwenderische Berechnungen zu vermeiden und den Speicherbedarf des Programms zu verringern. Dies sind die häufigsten Szenarien:
Wenn Sie ein Objekt haben, dessen Erstellung teuer ist und das Programm es möglicherweise nicht verwendet. Angenommen, Sie haben ein Kundenobjekt im Speicher, das über eine Orders-Eigenschaft verfügt, die ein großes Array von Order-Objekten enthält, für deren Initialisierung eine Datenbankverbindung erforderlich ist. Wenn der Benutzer niemals auffordert, die Bestellungen anzuzeigen oder die Daten für eine Berechnung zu verwenden, gibt es keinen Grund, Systemspeicher oder Rechenzyklen zum Erstellen zu verwenden. Indem Sie Lazy verwenden, um das Orders-Objekt für die verzögerte Initialisierung zu deklarieren, können Sie die Verschwendung von Systemressourcen vermeiden, wenn das Objekt nicht verwendet wird.
Wenn Sie ein Objekt haben, dessen Erstellung teuer ist, und dessen Erstellung erst nach Abschluss anderer teurer Vorgänge verschoben werden sollen. Angenommen, Ihr Programm lädt beim Start mehrere Objektinstanzen, von denen jedoch nur einige sofort erforderlich sind. Sie können die Startleistung des Programms verbessern, indem Sie die Initialisierung der Objekte verschieben, die erst erforderlich sind, wenn die erforderlichen Objekte erstellt wurden.
Obwohl Sie Ihren eigenen Code schreiben können, um eine verzögerte Initialisierung durchzuführen, empfehlen wir, stattdessen Lazy zu verwenden. Lazy und seine verwandten Typen unterstützen auch die Thread-Sicherheit und bieten eine konsistente Richtlinie zur Weitergabe von Ausnahmen.
quelle
//Lazy instantiation delays certain tasks. //It typically improves the startup time of a C# application. using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LazyLoad { class Program { static void Main(string[] args) { Lazy<MyClass> MyLazyClass = new Lazy<MyClass>(); // create lazy class Console.WriteLine("IsValueCreated = {0}",MyLazyClass.IsValueCreated); // print value to check if initialization is over MyClass sample = MyLazyClass.Value; // real value Creation Time Console.WriteLine("Length = {0}", sample.Length); // print array length Console.WriteLine("IsValueCreated = {0}", MyLazyClass.IsValueCreated); // print value to check if initialization is over Console.ReadLine(); } } class MyClass { int[] array; public MyClass() { array = new int[10]; } public int Length { get { return this.array.Length; } } } } // out put // IsValueCreated = False // Length = 10 // IsValueCreated = True
quelle
Was ich bisher über Lazy Init verstanden habe, ist, dass das Programm nicht alle Daten einmal lädt / anfordert. Es wartet auf die Verwendung, bevor es z. ein SQL-Server.
Wenn Sie eine Datenbank mit einer großen Tabelle haben, die mit einer großen Anzahl von Untertabellen verknüpft ist, und Sie nicht die Details benötigen, die aus den anderen Tabels verknüpft wurden, es sei denn, Sie gehen zu "Bearbeiten" oder "Details anzeigen", dann zu Lazy Init. wird der Anwendung helfen, schneller zu werden und zuerst die Detaildaten bei Bedarf "faul zu laden".
In SQL oder LINQ können Sie diese "Einstellung" in Ihrem Datenbankmodell pr festlegen. Datenelement.
Hoffe das macht Sinn für deine Frage?
Ein Webclient (z. B. ein Browser) macht dasselbe. Die Bilder werden nach dem HTML-Code "faul geladen" und AJAX ist auch eine "Art fauler Init", wenn sie richtig verwendet werden.
quelle
Die bisher erwähnten Datenbankbeispiele sind gut, aber nicht nur auf die Datenzugriffsschicht beschränkt. Sie können dieselben Prinzipien auf jede Situation anwenden, in der Leistung oder Speicher ein Problem darstellen können. Ein gutes Beispiel (obwohl nicht .NET) ist Cocoa, wo Sie warten können, bis der Benutzer ein Fenster anfordert, um es (und die zugehörigen Objekte) tatsächlich von der Schreibfeder zu laden. Dies kann dazu beitragen, die Speichernutzung gering zu halten und das anfängliche Laden der Anwendung zu beschleunigen, insbesondere wenn Sie über Dinge wie Einstellungsfenster sprechen, die, wenn überhaupt, erst zu einem späteren Zeitpunkt benötigt werden.
quelle