JavaScriptの配列の最大サイズ


108

コンテキスト:RSSフィードを読み取り、バックグラウンドでフィードを更新/チェックする小さなサイトを構築しています。表示するデータを格納する配列と、表示されたレコードのIDを格納する配列があります。

質問:物事が遅くなったり遅くなったりする前に、Javascriptで配列が保持できるアイテムの数 私は配列をソートしていませんが、jQueryのinArray関数を使用して比較を行っています。

Webサイトは実行されたままになり、更新されるため、ブラウザが頻繁に再起動/更新されることはほとんどありません。

配列からいくつかのレコードをクリアすることを考える必要がある場合、100アイテムのように、制限の後にいくつかのレコードを削除する最良の方法は何ですか。


3
ブラウザーがJSコードよりもツールバーからメモリーをリークすることで、より多くの問題に遭遇するでしょう。:) Firefox 4私はあなたに私の指を向けます。
epascarello、2011年

1
どのくらいの頻度でアレイをチェックしていますか(例2秒間隔)?何が遅いのか(例> 500ms)アレイの規模は何桁ですか(例:数千、数百万、数十億)?
zzzzBov 2011年

2
でベンチマークテストを行うjsperf.com
VirtualTroll

アレイを毎分チェックして更新します。そして、だいぶ遅いのは、そのロードとチェック、およびページ上の他のアニメーションに影響を及ぼし始めるパフォーマンスのヒットであり、申し訳ありません。
lovelovely

@Amineリンクへの感謝、そのウェブサイトが私の新しい親友になるようです:)
addlovely

回答:


153

「遅くなる」までの最大長は、ターゲットマシンと実際のコードに完全に依存するため、その(これらの)プラットフォームでテストして、何が許容可能かを確認する必要があります。

ただし、ECMA-262 5th Edition仕様による配列の最大長は、ToUint32抽象演算により符号なし32ビット整数によってバインドされるため、可能な最長の配列は2 32 -1 = 4,294,967,295 = 42.9億要素になる可能性があります。 。


13
@ Barkermn01:ECMA-262 5th Edition仕様では、配列の長さを変更するすべての操作で配列の長さをチェックするために抽象操作ToUint32を使用しているため、マシン(またはWebブラウザー)の基盤となるアーキテクチャは無関係であると思います。
maerics

1
hrm niceは、1つの素晴らしい64ビットブラウザが無意味に燃えていることを読んだだけです
Barkermn01

3
@ Barkermn01、64ビットブラウザーは、まだ他の多くの改善を施しています。ブラウザが行うことは、JavaScriptインタプリタであるだけではないことを覚えておいてください。
かみそりの嵐

1
Wowzerはそれがそれほど高くなるとは思っていませんでした。大丈夫、大丈夫だと思います!
lovelovely

実際、配列は最大で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
賢いアイデアですが、これを行うと、データが上書きされ、インデックスが混乱し、奇妙な動作が発生する可能性があります。
john ktejik 2014年

9
アイデアはリングバッファを実装することなので、そうです-意図的に古いデータを忘れて(それがリングバッファの使用目的です)、それが質問者が求めたものです。
Lelanthran 2014年

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
おかげで、配列の先頭からトリミングする必要があったため、スライスを使用することになりました。
lovelovely

3

@maericsが言ったように、ターゲットマシンとブラウザーがパフォーマンスを決定します。

しかし、実際の数値では、2017年のエンタープライズChromebookで操作を実行しています。

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 16msかかります、60fpsに十分です
  • x=4e6 250ミリ秒かかります。これは目立ちますが、大したことではありません
  • x=3e7 1300msかかります、これはかなり悪いです
  • x=4e7 11000msかかり、追加の2.5GBのメモリを割り当てます

つまり、JavaScript VMは4,000万要素の崖から落ち、おそらくプロセスをクラッシュさせるため、約3,000万要素がハード上限です。


2

私は何百万ものデータセットを操作してグラフ化するパフォーマンスフレームワークを構築しましたが、それでも、JavaScript計算のレイテンシは数十ミリ秒のオーダーでした。配列サイズの制限を超えることを心配しているのでない限り、それほど心配する必要はないと思います。


0

それは非常にブラウザに依存します。100アイテムは多くのように聞こえません-あなたはそれよりもはるかに高くなると思います。何千もの問題はないはずです。問題になる可能性があるのは、合計メモリ消費量です。


0

私は恥ずかしがらずにかなり大きなデータセットをメモリにプルしましたが、遅くなりましたが、データセットでかなり激しい計算を行うと、15ヶ月以上のデータが必要になりました。データの計算が非常に多く、行数が多い場合を除いて、メモリの問題が発生することはないと思います。異なるモック結果セットを使用したプロファイリングとベンチマークは、パフォーマンスを評価するための最善の方法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.