Максимальный размер массива в Javascript

108

Контекст: я создаю небольшой сайт, который читает RSS-канал и обновляет / проверяет его в фоновом режиме. У меня есть один массив для хранения отображаемых данных и другой, в котором хранятся идентификаторы показанных записей.

Вопрос: сколько элементов может содержать массив в Javascript, прежде чем работа станет медленной или вялой. Я не сортирую массив, но использую функцию jQuery inArray для сравнения.

Веб-сайт будет продолжать работать и обновляться, и маловероятно, что браузер будет перезапускаться / обновляться так часто.

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

добавлен
источник
3
Вероятно, вы столкнетесь с большим количеством проблем, связанных с утечкой памяти браузером из панелей инструментов, чем из-за кода JS. :) Firefox 4 Я показываю на тебя пальцем.
epascarello
1
Как часто вы проверяете массив (например, интервал 2 с)? Что считается вялым (например,> 500 мс)? Какого порядка величины ваш массив (например, тысячи, миллионы, миллиарды)?
zzzzBov
2
провести тестирование производительности с помощью jsperf.com
VirtualTroll
Я буду проверять и обновлять массив каждую минуту. И да, медленным будет удар по производительности, который начнет влиять на эту загрузку и проверку, а также на другие анимации на странице, трудно определить, извините!
добавлено мило
@Amine, спасибо за ссылку, похоже, этот сайт станет моим новым лучшим другом :)
добавлено мило

Ответы:

153

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

Тем не менее, максимальная длина массива в соответствии с ECMA-262 5th Edition , спецификации связан беззнаковое 32-битное целое число из - за ToUint32 абстрактной операции, так что самый длинный возможный массив может иметь 2 32 -1 = 4294967295 = 4,29 миллиарда элементов .

maerics
источник
13
@ Barkermn01: спецификация ECMA-262 5th Edition использует абстрактную операцию ToUint32 для проверки длины массива при любой операции, которая изменяет его длину, поэтому я думаю, что базовая архитектура машины (или веб-браузера) не имеет значения.
maerics
1
хрм приятно, только что прочитал, что один ужасный 64-битный браузер бесполезен,
Barkermn01
3
@ Barkermn01, в 64-битных браузерах еще много улучшений. Помните, что быть интерпретатором javascript - это не единственное, чем занимается браузер.
Razor Storm
1
Ваузер даже не ожидал, что это будет так высоко. Хорошо, я думаю, со мной все будет хорошо!
добавлено мило
Фактически в массиве может быть не более 4294967295 (2 ^ 31-1) элементов. См stackoverflow.com/a/12766547/396458
NullUserException
26

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

Например:

var container = new Array ();
var maxlen = 100;
var index = 0;

// 'store' 1538 items (only the last 'maxlen' items are kept)
for (var i=0; i<1538; i++) {
   container [index++ % maxlen] = "storing" + i;
}

// get element at index 11 (you want the 11th item in the array)
eleventh = container [(index + 11) % maxlen];

// get element at index 11 (you want the 11th item in the array)
thirtyfifth = container [(index + 35) % maxlen];

// print out all 100 elements that we have left in the array, note
// that it doesn't matter if we address past 100 - circular buffer
// so we'll simply get back to the beginning if we do that.
for (i=0; i<200; i++) {
   document.write (container[(index + i) % maxlen] + "<br>\n");
}
Лелантран
источник
4
Умная идея, но, сделав это, вы можете перезаписать данные, запутать индексы и, возможно, привести к странному поведению.
Джон Ктеджик
9
Идея состоит в том, чтобы реализовать кольцевой буфер, так что да - вы намеренно «забываете» старые данные (для этого используется кольцевой буфер), и именно об этом просил спрашивающий.
Lelanthran
1
Мне было просто скучно щелкать SO и нашел этот ответ. люблю технику перезаписи индексов по мере необходимости.
Кайл Хотчкисс
5

Вы можете попробовать что-то вроде этого, чтобы проверить и обрезать длину:

http://jsfiddle.net/orolo/wJDXL/

var longArray = [1, 2, 3, 4, 5, 6, 7, 8];

if (longArray.length >= 6) {
  longArray.length = 3;
}

alert(longArray); //1, 2, 3

ороло
источник
2
Закончилось использованием среза, так как мне нужно было обрезать с начала массива, хотя, спасибо.
добавлено мило
3

Как сказал @maerics, ваша целевая машина и браузер будут определять производительность.

Но для некоторых реальных цифр на моем корпоративном Chromebook 2017 года выполняется операция:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 занимает 16 мс, достаточно для 60 кадров в секунду
  • x=4e6 занимает 250 мс, что заметно, но не имеет большого значения
  • x=3e7 занимает 1300 мс, что довольно плохо
  • x=4e7 занимает 11000 мс и выделяет дополнительно 2,5 ГБ памяти

Таким образом, около 30 миллионов элементов - это жесткий верхний предел, потому что виртуальная машина javascript падает с обрыва на 40 миллионах элементов и, вероятно, приведет к сбою процесса.

Карл Уолш
источник
2

Я создал платформу производительности, которая управляет миллионами наборов данных и отображает их в графиках, и даже тогда задержка вычисления javascript составляла порядка десятков миллисекунд. Если вы не беспокоитесь о превышении предельного размера массива, я не думаю, что вам есть о чем беспокоиться.

Бритва Буря
источник
0

Это будет сильно зависеть от браузера. 100 предметов не звучат как большое количество - я думаю, вы могли бы пойти намного выше этого. Тысячи - не проблема. Что может быть проблемой, так это общее потребление памяти.

Rjmunro
источник
0

Я без зазрения совести вытащил несколько довольно больших наборов данных в память, и хотя это действительно стало медленным, потребовалось, может быть, 15 млн данных вверх с довольно интенсивными вычислениями в наборе данных. Я сомневаюсь, что у вас возникнут проблемы с памятью, если у вас не будут интенсивные вычисления с данными и большим количеством строк. Профилирование и сравнительный анализ с различными фиктивными наборами результатов будут вашим лучшим выбором для оценки производительности.

стефгосселин
источник