Объект Javascript Big-O

Начиная с Java, объект Javascript напоминает мне HashMap в Java.

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]");

В Java HashMap используется функция hashcode() ключа для определения местоположения (записей) ведра для хранения и извлечения. В большинстве случаев для основных операций, таких как put() и get(), производительность является постоянным временем, пока не произойдет столкновение хэшей, которое становится O (n) для этих основных операций, потому что оно образует связанный список, чтобы сохранить столкновений.

Мой вопрос:

  • Как Javascript хранит объект?
  • Какова производительность операций?
  • Будут ли какие-либо столкновения или другие сценарии, которые ухудшат производительность, как в Java

Спасибо!

Ответы

Ответ 1

Javascript выглядит так, будто он хранит вещи на карте, но это обычно не так. Вы можете получить доступ ко всем свойствам объекта, как к индексу на карте, и назначить новые свойства во время выполнения, но код поддержки намного быстрее и сложнее, чем просто использовать карту.

Ничего не требуется, чтобы виртуальные машины не использовали карту, но большинство из них пытаются обнаружить структуру объекта и создать эффективное представление в памяти для этой структуры. Это может привести к большому количеству оптимизаций (и деоптов) во время работы программы, и это очень сложная ситуация.

Это сообщение в блоге, связанное в комментариях к комментарию от @Zirak, имеет довольно хорошее обсуждение общих структур и когда виртуальные машины могут переключаться от структуры к карте. Это часто может показаться непредсказуемым, но в значительной степени основано на наборе эвристик в виртуальной машине и количестве различных объектов, которые, по его мнению, он видел. Это в значительной степени связано со свойствами (и их типами) возвращаемых значений и, как правило, сосредоточено вокруг каждой функции (особенно функций-конструкторов).

Есть несколько вопросов и статей, которые копаются в деталях (но, надеюсь, все еще понятны без тонны фона):

Производительность сильно зависит от вышеизложенного. В худшем случае должен быть доступ к карте, лучший случай - прямой доступ к памяти (возможно, даже deref).

Существует большое количество сценариев, которые могут влиять на производительность, особенно учитывая, как JITTER и VM будут создавать и уничтожать скрытые классы во время выполнения, поскольку они видят новые варианты объекта. Внезапно столкнувшись с новым вариантом объекта, который, как предполагалось, был мономорфным, может привести к тому, что виртуальная машина вернется к менее оптимальному представлению и перестанет обрабатывать объект как структуру в памяти, но логика вокруг этого довольно сложная и хорошо -covered в этот пост в блоге.

Вы можете помочь, убедившись, что объекты, созданные из одного и того же конструктора, имеют тенденцию иметь очень похожие структуры и делают вещи такими же предсказуемыми, насколько это возможно (полезно для вас, для обслуживания и для виртуальной машины). Обладая известными свойствами для каждого объекта, задавайте типы для этих свойств и создавая объекты из конструкторов, когда вы можете позволить вам ударить большую часть доступных оптимизаций и получить очень быстрый код.