Максимальний розмір масиву в JavaScript


108

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

Запитання: Скільки елементів може містити масив у Javascript, перш ніж все почне повільно або мляво. Я не сортую масив, але використовую функцію jQuery inArray для порівняння.

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

Якщо мені варто подумати про очищення деяких записів з масиву, який найкращий спосіб видалити деякі записи після обмеження, як 100 елементів.


3
Напевно, у вас виникне більше проблем із протіканням пам'яті браузера з панелей інструментів, ніж з кодом JS. :) Firefox 4 Я вказую пальцем на тебе.
epascarello

1
Як часто ви перевіряєте масив (колишній інтервал 2s)? Що являє собою млявий (колишній> 500 мс)? Який порядок розмірів - це ваш масив (колишні тисячі, мільйони, мільярди)?
zzzzBov

2
робити тестові показники з jsperf.com
VirtualTroll

Я буду перевіряти та оновлювати масив щохвилини. І так млявий був би хіт продуктивності, який починає здійснювати це завантаження та перевірку, та інші анімації на сторінці, важко визначити вибачте!
додано

@Amine спасибі за посилання, схоже, що веб-сайт буде моїм новим найкращим другом :)
addedlovely

Відповіді:


153

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

Однак максимальна довжина масиву згідно специфікації ECMA-262 5th Edition обмежена неподписаним 32-бітовим цілим числом завдяки абстрактній операції ToUint32 , тому найдовший можливий масив може мати 2 32 -1 = 4,294,967,295 = 4,29 мільярда елементів .


13
@ Barkermn01: специфікація 5-го видання ECMA-262 використовує абстрактну операцію ToUint32 для перевірки довжини масиву для будь-якої операції, яка змінює його довжину, тому я вважаю, що основна архітектура машини (або веб-браузера) не має значення.
maerics

1
Хрм приємно щойно прочитав, що один дивовижний браузер 64Bit тоді
пламеть

3
@ Barkermn01, 64-розрядні браузери все ще мають багато інших удосконалень. Пам'ятайте, що перекладач javascript - не єдине, що робить браузер.
Буря бритви

1
Воузер не очікував, що він буде таким високим. Добре, добре, я думаю, що я буду добре!
додановелико

Насправді масив може містити не більше 4294967295 (2 ^ 31-1) елементів. Див stackoverflow.com/a/12766547/396458
NullUserException

26

Не потрібно обрізати масив, просто адресуйте його як круговий буфер (index% 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
Розумна ідея, але виконуючи це, ви зможете перезаписати дані, заплутати індекси та, можливо, призвести до дивної поведінки.
John ktejik

9
Ідея полягає в тому, щоб реалізувати буфер кільця, так що так - ви навмисно "забуваєте" старі дані (саме для цього використовується буфер кільця) і саме це запитував запитувач.
Лелантран

1
Мені просто нудно було клацати навколо SO та знайшов цю відповідь. любите техніку із перезаписом індексів за потребою.
Kyle Hotchkiss

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 мільйонів елементів є важкою верхньою межею, тому що jama VM падає з обриву на 40 мільйонів елементів і, ймовірно, приведе до краху процес.


2

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


0

Це буде дуже залежно від браузера. 100 предметів не схоже на велику кількість - я думаю, ви могли б набагато перевищити це. Тисячі не повинні бути проблемою. Проблема може полягати в загальному споживанні пам'яті.


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.