Wird der Compiler die Initialisierung der Collections optimieren?

8

Wird der Compiler diesen Code optimieren oder wird die Sammlung nach jedem Methodenaufruf initialisiert?

%Vor%

Wenn die Antwort negativ ist, empfehle ich, diese Lösung zu verwenden: Erstellen einer Konstante Wörterbuch in C #

    
astef 14.11.2014, 08:31
quelle

3 Antworten

13

Wenn solch eine Frage auftaucht und Sie nicht sicher sind, was die Antwort ist, ist es immer gut, "unter die Haube" zu schauen.

Dies ist die IL, die der Compiler mit eingeschaltetem Optimierer erzeugt hat:

%Vor%

Wie Sie sehen können, ruft es newobj auf, um Dictionary<K,V> jedesmal zuzuweisen , lädt sowohl lokal als auch Aufrufe Dictionary.Add jedes Mal (das ist das syntaktische Zuckeräquivalent) von Add aufrufen). Es hat keine engen Kenntnisse mit dem Typ, um die Erstellung der Objekte zwischenzuspeichern.

    
Yuval Itzchakov 14.11.2014, 08:53
quelle
6

Nein, wird es nicht. Es hat kein intrinsisches Wissen darüber, was ein Dictionary ist. Für den Compiler ist es nur eine normale Klasse, daher weiß es nicht, dass die Instanz in diesem speziellen Fall wiederverwenden könnte.

Dies wäre der richtige Weg, dies zu tun:

%Vor%

Dieser Ansatz funktioniert, weil Sie wissen, was das Objekt tut, und Sie wissen auch, dass es nie geändert wird.

Merken Sie sich folgende Syntax:

%Vor%

Ist nur syntaktischer Zucker dafür:

%Vor%

Die einzige Voraussetzung, damit dies mit any -Klassen funktioniert, ist für die Klasse

  • Implementieren IEnumerable
  • Habe eine öffentliche Add -Methode.

Sie haben vorgeschlagen, eine switch -Anweisung zu verwenden, aber der Dictionary -Ansatz kann flexibler sein. Betrachten Sie zum Beispiel einen anderen Gleichheitsvergleich (wie StringComparer.OrdinalIgnoreCase ). Es ist besser, wenn% code_% dies mit dem richtigen Vergleicher behandelt als mit Dictionary .

    
Lucas Trzesniewski 14.11.2014 08:44
quelle
2

Nein, C #, wie es steht, wird das in keiner Weise "optimieren" - und ich bezweifle ernsthaft, dass das jemals der Fall sein wird.

Während Sie vielleicht argumentieren, dass dieser spezielle Code optimiert werden könnte, handelt es sich in Wirklichkeit um einen Grenzfall, der zur Kompilierungszeit nicht so einfach zu bestimmen ist. Um Ihnen ein Gegenbeispiel zu geben - was wäre, wenn eines Ihrer String-Literale Mitglied einer anderen Klasse wäre? Was wäre, wenn Sie ein benutzerdefiniertes Wörterbuch hätten (und es gibt keine spezielle Behandlung für die vorhandene Wörterbuchklasse), die in ihrem Konstruktor etwas Unkonventionelles getan hat?

    
decPL 14.11.2014 08:43
quelle