2015-02-04 12 views
14

Von Java kommend, erinnert mich das Javascript-Objekt an HashMap in Java.Javascript Objekt Big-O

Javascript:

var myObject = { 
    firstName: "Foo", 
    lastName: "Bar", 
    email: "[email protected]" 
}; 

Java:

HashMap<String, String> myHashMap = new HashMap<String, String>(); 
myHashMap.put("firstName", "Foo"); 
myHashMap.put("lastName", "Bar"); 
myHashMap.put("email", "[email protected]"); 

In Java HashMap, verwendet es die Hash-Code() Funktion der Taste den Kübel Standort (Einträge) für die Speicherung und Abruf zu bestimmen. Die meiste Zeit, für grundlegende Operationen wie put() und get(), ist die Leistung konstante Zeit, bis eine Hash-Kollision auftritt, die O (n) für diese grundlegenden Operationen wird, weil sie eine verknüpfte Liste bildet, um die zu speichern kollidierte Einträge.

Meine Frage ist:

  1. Wie JavaScript-Objekt speichert?
  2. Was ist die Leistung von Operationen?
  3. Wird es jemals eine Kollision oder andere Szenarien, die die Leistung wie in Java

Dank verschlechtert!

+0

lesen Sie in diesem Link, es hat einige gute Informationen über Ihre Frage: https://github.com/benblack86/java-snippets/blob/master/resources/java_collections.pdf –

+1

@EvanBechtol, dass das Papier im Begriff ist ** Java **, und diese Frage bezieht sich auf ** JavaScript ** Leistung. – Pointy

+2

Objektspeicher ist implementierungsabhängig. Das heißt, diese Frage kann für v8 und spidermonkey beantwortet werden, aber das sind lange Antworten. –

Antwort

9

Javascript sieht so aus, als ob es Dinge in einer Karte speichert, aber das ist normalerweise nicht der Fall. Sie können auf die meisten Eigenschaften eines Objekts wie auf einen Index in einer Map zugreifen und zur Laufzeit neue Eigenschaften zuweisen. Der Backing-Code ist jedoch viel schneller und komplizierter als die Verwendung einer Map.

Es gibt keine Notwendigkeit, dass VMs keine Map verwenden, aber die meisten versuchen, die Struktur des Objekts zu erkennen und eine effiziente In-Memory-Repräsentation für diese Struktur zu erstellen. Dies kann zu einer Menge von Optimierungen führen, während das Programm läuft, und es ist eine sehr komplizierte Situation.

This blog post, in der Frage Kommentare von @Zirak verknüpft, hat eine ziemlich gute Diskussion der gemeinsamen Strukturen und wenn VMs von einer Struktur zu einer Karte wechseln können. Es kann oft unvorhersehbar erscheinen, basiert aber größtenteils auf einer Reihe von Heuristiken innerhalb der VM und auf der Anzahl der verschiedenen Objekte, von denen sie glaubt, dass sie gesehen wurden. Das hängt größtenteils mit den Eigenschaften (und ihren Typen) von Rückgabewerten zusammen und neigt dazu, um jede Funktion herum zentriert zu sein (insbesondere Konstruktorfunktionen).

Es gibt ein paar Fragen und Artikel, die in die Details zu graben (aber hoffentlich noch verständlich ohne eine Tonne Hintergrund):

Die Leistung variiert stark, basierend auf dem oben genannten. Der schlimmste Fall sollte ein Kartenzugriff sein, am besten ist ein direkter Speicherzugriff (vielleicht sogar ein Deref).

Es gibt eine große Anzahl von Szenarien, die Auswirkungen auf die Leistung haben können, insbesondere wenn JITter und VM versteckte Klassen zur Laufzeit erstellen und löschen, da sie neue Variationen eines Objekts sehen.Plötzlich kann eine neue Variante eines zuvor als monomorph angenommenen Objekts dazu führen, dass die VM zu einer weniger optimalen Darstellung zurückkehrt und das Objekt nicht mehr als In-Memory-Struktur behandelt, aber die Logik dafür ist ziemlich kompliziert und gut -bedeckt in this blog post.

Sie können helfen, indem Sie sicherstellen, dass Objekte, die vom selben Konstruktor erstellt werden, dazu neigen, sehr ähnliche Strukturen zu haben und Dinge so vorhersehbar wie möglich zu machen (gut für Sie, Wartung und die VM). Eigenschaften für jedes Objekt kennen zu lernen, Typen für diese Eigenschaften festzulegen und Objekte aus Konstruktoren zu erstellen, wenn Sie können, sollten Sie die meisten der verfügbaren Optimierungen treffen lassen und extrem schnellen Code haben.