Подтвердить что ты не робот

Javascript ES6 вычислительная/временная сложность коллекций

Какая временная сложность (в примечаниях с большим О) предоставляется спецификацией ES6 для Keyed Collections (Set, Map, WeakSet и WeakMap)?

Мое ожидание, и я ожидаю, что у большинства разработчиков заключается в том, что спецификации и реализации будут использовать широко принятые алгоритмы исполнения, в этом случае Set.prototype.has, add и delete для всех O (1) в среднем случае. То же самое для эквивалентов Map и Weak–.

Мне не совсем очевидно, была ли задана временная сложность реализации, например. в Спецификация языка ECMAScript 2015 - 6-е издание - 23.2 Установка объектов.

Если я не пойму это (и это, конечно, очень возможно), то, похоже, спецификация ECMA требует, чтобы реализации (например, Set.prototype.has) использовали алгоритм линейного времени (O (n)). Мне было бы чрезвычайно удивительно, что более эффективные алгоритмы не были бы санкционированы или даже разрешены спецификацией, и мне было бы очень интересно объяснить, почему это так.

4b9b3361

Ответ 1

Прямо из этого самого абзаца, связанного с:

Установить объекты должны быть реализованы с помощью [механизмов], которые в среднем обеспечивают время доступа, которое является сублинейным по количеству элементов в коллекции.

Вы найдете то же предложение для Карт, WeakMaps и WeakSets.

Похоже, спецификация ECMA указывает, что реализации (например, Set.prototype.has) должны использовать алгоритм линейного времени (O(n)).

<Не p > Нет:

Структуры данных, используемые в этой спецификации объектов Set, предназначены только для описания требуемой наблюдаемой семантики объектов Set. Он не предназначен для жизнеспособной модели реализации.

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

Ответ 2

Для тех, кто интересуется, я сделал очень быстрый тест:

const benchmarkMap = size => {
  console.time('benchmarkMap');
  var map = new Map();
  for (var i = 0; i < size; i++) map.set(i, i);
  for (var i = 0; i < size; i++) var x = map.get(i);
  console.timeEnd('benchmarkMap');
}

const benchmarkObj = size => {
  console.time('benchmarkObj');
  var obj = {};
  for (var i = 0; i < size; i++) obj[i] = i;
  for (var i = 0; i < size; i++) var x = obj[i];
  console.timeEnd('benchmarkObj');
}

var size = 1000000;

benchmarkMap(size);
benchmarkObj(size);

Я запустил это несколько раз и дал следующие результаты:

(MacBook Pro 2017, 2,5 ГГц i7 с 16 ГБ ОЗУ)

benchmarkMap: 189.120ms
benchmarkObj: 44.214ms

benchmarkMap: 200.817ms
benchmarkObj: 38.963ms

benchmarkMap: 187.968ms
benchmarkObj: 41.633ms

benchmarkMap: 186.533ms
benchmarkObj: 35.850ms

benchmarkMap: 187.339ms
benchmarkObj: 44.515ms