Создание массива размером n за O (1) теоретически возможно в зависимости от деталей реализации - в принципе, если массив реализован как хеш-таблица, его свойство length
можно установить без выделение или инициализация пространства для всех его элементов. Спецификация ECMAScript для конструктора Array(n)
не обязывает Array(n)
делать что-либо, что обязательно занимает больше O (1) времени, хотя также не требует, чтобы сложность времени была O (1).
На практике сложность времени Array(n)
зависит от браузера, хотя проверить это немного сложно. Функцию performance.now()
можно использовать для измерения времени, прошедшего между началом и концом вычисления, но точность этой функции во многих браузерах искусственно снижается для защиты от атак с тактовой частотой процессора, таких как Spectre. Чтобы обойти это, мы можем вызвать конструктор repetitions
раз, а затем разделить прошедшее время на repetitions
, чтобы получить более точное измерение для вызова конструктора.
Мой временной код приведен ниже:
function timeArray(n, repetitions=100000) {
var startTime = performance.now();
for(var i = 0; i < repetitions; ++i) {
var arr = Array(n);
arr[n-1] = 'foo';
}
var endTime = performance.now();
return (endTime - startTime) / repetitions;
}
for(var n = 10000; n <= 1000000; n += 10000) {
console.log(n, timeArray(n));
}
Вот мои результаты от Google Chrome (версия 74) и Firefox (версия 72); на Chrome производительность явно O (n), а на Firefox это явно O (1) с довольно постоянным временем около 0,01 мс на моей машине.
Я измерил с помощью repetitions = 1000
на Chrome и repetitions = 100000
на Firefox, чтобы получить достаточно точные результаты в разумные сроки.
Еще один вариант, предложенный @M. Дитц в комментариях должен объявить массив как var arr = [];
, а затем назначить его по некоторому индексу (например, arr[n-1] = 'foo';
). Оказывается, что на O (1) требуется время как Chrome, так и Firefox, оба последовательно в течение одной наносекунды:
Это предполагает версию с []
лучше использовать, чем версию с Array(n)
, но, тем не менее, спецификация не требует, чтобы это занимало O (1) время, поэтому могут быть другие браузеры, где эта версия занимает O (n) время , Если кто-то получит другие результаты в другом браузере (или другой версии одного из этих браузеров), добавьте комментарий.