2013-10-31 11 views
5

In "C# in der Tiefe" von Jon Skeet lese ich, dass (p 511).:Arrays haben direkte Unterstützung in der CLR

Alle Arrays aus System.Array ableiten, und sie sind die einzige Sammlungen mit direkte Unterstützung in der CLR (Mein Schwerpunkt).

Ich frage mich, was das genau bedeutet, vor allem in Bezug auf Typen, die diese Unterstützung nicht haben. Sind alle Typen, die diese Unterstützung nicht haben, aus Typen zusammengestellt, die von der CLR ausgeführt werden, wenn sie IL interpretiert? Sind Typen, die diese Unterstützung nicht haben, von der CLR nicht "bekannt"?

Auch auf p. 512 des Buchs:

Der C# -Compiler hat eine integrierte Unterstützung für Arrays in einer Reihe von Möglichkeiten.

Enthält diese in irgendeiner Weise betreffen die direkte Unterstützung der Array-Typ in der CLR hat oder sind diese zwei verschiedene Dinge zusammen?

+0

Scheint albern, eine Antwort zu versuchen, wenn Mr Skeet selbst wahrscheinlich eine viel bessere Antwort anbieten kann ... :) –

+2

Werfen Sie einen Blick auf [Liste der CIL Anweisungen] (http://en.wikipedia.org/wiki/List_of_CIL_instructions). Es gibt viele Opcodes, die sich mit Arrays befassen, aber keine, die sich mit anderen Sammlungen befassen. – tom

Antwort

7

Wie beschrieben, existieren Arrays tief in der CLR. Es gibt IL-Anweisungen für die Interaktion mit ihnen (ldelem.*/stelem.*). Sie haben eine Vordatierung für Generika und ermöglichen dennoch die Erstellung von Arrays unterschiedlicher Typen nach Bedarf. Dies ist bei anderen Auflistungstypen nicht der Fall. Beispiel: List<T> ist ein Wrapper, der über ein Array vorhanden ist. Die CLR benötigt keine speziellen Kenntnisse von List<T> - nur reguläre IL, die auf den Inhalt vorhandener Arrays zugreift oder neue Arrays zuweist. Die andere Hauptform der Sammlung sind verknüpfte Listen (und ähnliche; Bäume usw.) - aber wiederum benötigen diese keine spezielle Unterstützung - dies sind nur Objekte, die sich mit Referenzen verbinden.

4

Ja, die Triade von Compiler, Jitter und CLR haben viele eingebaute Kenntnisse von Arrays. Dies ist ziemlich wichtig für jede Sprachlaufzeit, es kann die Fähigkeiten des Prozessors nicht ignorieren. Damit Code effizient ausgeführt werden kann, muss er dem entsprechen, was ein Prozessor gut kann.

Das ist nicht viel, Prozessoren sind eher einfache Geräte. Sie bieten keine echte Unterstützung für die Art von Datenstrukturen, die Sie gerne in einem Programm verwenden. Die Art und Weise, wie eine Sprache und eine Laufzeitumgebung entworfen werden, zeigt eine Menge zugrunde liegender Prozessorimplementierungsdetails.

Der Begriff eines Stapels ist vorhanden überall zum Beispiel. Eine kleine Menge an Speicher, auf die ein Prozessor direkt über seinen Stapelzeiger zugreifen kann. Deshalb hat die C# -Sprache, wie fast jede andere Sprache, die Vorstellung einer lokalen Variablen innerhalb einer Methode. Das ist eine Variable, die auf dem Stapel gespeichert wird. Der Prozessor unterstützt auch stark die Idee, Methoden mit Argumenten aufzurufen, die einen einzelnen Wert liefern, der in jeder Sprache universell ist. Die geringe Menge an Speicher, die dem Stack zugewiesen wurde, gab dieser Site ihren Namen.

Werttypen sind ein weiteres .NET-Beispiel für zugrunde liegende Prozessordetails. Sie stellen direkt dar, was ein Prozessor im Umgang mit Werten gut kann. Eine int direkt auf Prozessorregister zum Beispiel zugeordnet. Float und Double werden direkt der Fähigkeit des Prozessors zugeordnet, diese Werte zu speichern und Fließkommaanweisungen mit diesen beiden Typen auszuführen.

Und ein Array ist die einzige Datenstruktur, die ein Prozessor unterstützen kann. Sehr einfach, ein Stück Speicher mit einem Zeiger, um auf diesen Speicher zuzugreifen.Sehr stark in .NET optimiert, um das so effizient wie möglich zu machen. Mit einem besonderen Hinweis auf "Vektor", ein Array-Typ, der speziell behandelt wird. Ein eindimensionales Array mit einem Startindex von 0, dem Array-Typ, der direkt der Prozessorunterstützung zugeordnet wird. Sie erhalten einen Vektor in C# mit der type[] Deklaration. Sie sehen auch die Array-Einschränkungen zurück, .NET macht es sehr schwierig, ein Array mit einem Startindex zu erstellen, der nicht 0 ist. Aus einem sehr guten Grund ist die Indizierung eines solchen Arrays teuer, da es eine zusätzliche Subtraktion zum Abbilden des Arrays erfordert Index zu dem Stück Speicher. Die Array-Index-Überprüfung ist ein weiteres starkes Ziel für die Optimierung, die Überprüfung von Grenzen ist teuer. Es gibt viele intelligente Funktionen, die in den Jitter integriert sind, um zu erkennen, dass eine Schleife ein Array niemals außerhalb der Grenzen indexieren kann, wodurch die Indexprüfung vollständig eliminiert werden kann.

Jede Datenstruktur muss auf der Prozessorunterstützung für nur nackte Arrays aufgebaut werden. Aus diesem Grund finden Sie das innerhalb der .NET-Auflistungsklassen. Ohne zusätzliche Hilfe von der CLR oder Jitter, da es wenig gibt, was sie tun können, um es schneller zu machen. Auch der Grund, dass diese Auflistungsklassen alle auf Vektorfeldern aufgebaut sind. Wie Liste <>, keine Liste, die der Art ähnelt, die Sie in Ihrem Datenalgorithmus Lehrbuch überhaupt sehen, eigentlich ein Array. Oder Wörterbuch <>, der Antipode eines Arrays, aber immer noch mit ihnen implementiert.

+0

Vielen Dank für diese ausführliche Antwort. Macht die Konzepte viel klarer. – bump