Kích thước tối đa của một mảng trong Javascript


108

Bối cảnh: Tôi đang xây dựng một trang web nhỏ đọc nguồn cấp dữ liệu rss và cập nhật / kiểm tra nguồn cấp dữ liệu trong nền. Tôi có một mảng để lưu trữ dữ liệu để hiển thị và một mảng khác lưu trữ các bản ghi ID đã được hiển thị.

Câu hỏi: Một mảng có thể chứa bao nhiêu mục trong Javascript trước khi mọi thứ bắt đầu chậm hoặc chậm chạp. Tôi không sắp xếp mảng, nhưng đang sử dụng hàm inArray của jQuery để so sánh.

Trang web sẽ vẫn chạy và cập nhật và có khả năng trình duyệt sẽ không được khởi động lại / làm mới thường xuyên.

Nếu tôi nên nghĩ về việc xóa một số bản ghi khỏi mảng, thì cách tốt nhất để xóa một số bản ghi sau một giới hạn, như 100 mục là gì.


3
Bạn có thể sẽ gặp nhiều sự cố hơn với trình duyệt làm rò rỉ bộ nhớ từ các thanh công cụ hơn là từ mã JS. :) Firefox 4 Tôi chỉ tay vào bạn.
epascarello

1
Bạn có thường xuyên kiểm tra mảng (ví dụ khoảng 2 giây) không? Điều gì tạo nên sự chậm chạp (ví dụ> 500ms)? Mảng của bạn có thứ tự độ lớn nào (ví dụ: hàng nghìn, hàng triệu, hàng tỷ)?
zzzzBov

2
thực hiện kiểm tra điểm chuẩn với jsperf.com
VirtualTroll

Tôi sẽ kiểm tra và cập nhật mảng mỗi phút. Và vâng, chậm chạp sẽ là một cú đánh hiệu suất bắt đầu ảnh hưởng đến quá trình tải và kiểm tra đó cũng như các hoạt ảnh khác trên trang, rất khó để xác định, xin lỗi!
thêm vào

@Amine cảm ơn vì liên kết, có vẻ như trang web đó sẽ là bạn thân mới của tôi :)
thêm vào

Câu trả lời:


153

Độ dài tối đa cho đến khi "nó hoạt động chậm chạp" hoàn toàn phụ thuộc vào máy mục tiêu và mã thực của bạn, vì vậy bạn sẽ cần kiểm tra trên (các) nền tảng đó để xem điều gì có thể chấp nhận được.

Tuy nhiên, độ dài tối đa của một mảng theo đặc tả ECMA-262 5th Edition bị ràng buộc bởi một số nguyên 32 bit không dấu do thao tác trừu tượng ToUint32 , vì vậy mảng dài nhất có thể có 2 32 -1 = 4,294,967,295 = 4,29 tỷ phần tử .


13
@ Barkermn01: đặc tả ECMA-262 5th Edition sử dụng thao tác trừu tượng ToUint32 để kiểm tra độ dài của một mảng trên bất kỳ thao tác nào sửa đổi độ dài của nó, vì vậy tôi nghĩ rằng kiến ​​trúc cơ bản của máy (hoặc trình duyệt web) là không liên quan.
maerics

1
hrm tuyệt vời chỉ cần đọc rằng một trình duyệt 64Bit tuyệt vời đang bốc cháy vô nghĩa sau đó,
Barkermn01

3
@ Barkermn01, các trình duyệt 64bit vẫn có rất nhiều cải tiến khác. Hãy nhớ rằng trở thành một trình thông dịch javascript không phải là điều duy nhất mà một trình duyệt làm.
Razor Storm

1
Wowzer không ngờ nó lại cao như vậy. OK, tôi nghĩ tôi sẽ ổn!
thêm vào

Trên thực tế, một mảng có thể có nhiều nhất 4294967295 (2 ^ 31-1) phần tử. Xem stackoverflow.com/a/12766547/396458
NullUserException

26

Không cần phải cắt mảng, chỉ cần giải quyết nó như một vùng đệm tròn (chỉ mục% maxlen). Điều này sẽ đảm bảo nó không bao giờ vượt quá giới hạn (triển khai bộ đệm hình tròn có nghĩa là khi bạn đi đến cuối, bạn quay lại từ đầu - không thể vượt quá phần cuối của mảng).

Ví dụ:

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
Ý tưởng thông minh, nhưng bằng cách làm này, bạn sẽ có khả năng ghi đè dữ liệu, gây nhầm lẫn các chỉ mục và có thể dẫn đến hành vi lạ.
john ktejik

9
Ý tưởng là thực hiện một bộ đệm vòng, vì vậy có - bạn đang cố tình "quên" dữ liệu cũ (đó là những gì bộ đệm vòng được sử dụng) và đó là những gì người hỏi yêu cầu.
Lelanthran

1
Tôi chỉ buồn chán khi nhấp vào SO và tìm thấy phản hồi này. yêu thích kỹ thuật ghi đè các chỉ mục khi cần thiết.
Kyle Hotchkiss

5

Bạn có thể thử một cái gì đó như thế này để kiểm tra và cắt bớt độ dài:

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
Đã kết thúc bằng cách sử dụng slice khi tôi cần cắt từ đầu mảng, cảm ơn.
thêm vào

3

Giống như @maerics đã nói, máy mục tiêu và trình duyệt của bạn sẽ quyết định hiệu suất.

Nhưng đối với một số con số trong thế giới thực, trên Chromebook doanh nghiệp 2017 của tôi, đang chạy hoạt động:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 mất 16ms, đủ tốt cho 60 khung hình / giây
  • x=4e6 mất 250ms, đáng chú ý nhưng không phải là vấn đề lớn
  • x=3e7 mất 1300ms, khá tệ
  • x=4e7 mất 11000ms và phân bổ thêm 2,5GB bộ nhớ

Vì vậy, khoảng 30 triệu phần tử là một giới hạn trên khó, bởi vì máy ảo javascript rơi ra khỏi vách đá ở mức 40 triệu phần tử và có thể sẽ làm hỏng quá trình.


2

Tôi đã xây dựng một khung hiệu suất thao tác và vẽ biểu đồ hàng triệu tập dữ liệu, và thậm chí sau đó, độ trễ tính toán javascript theo thứ tự hàng chục mili giây. Trừ khi bạn lo lắng về việc vượt quá giới hạn kích thước mảng, tôi không nghĩ bạn phải lo lắng nhiều.


0

Nó sẽ rất phụ thuộc vào trình duyệt. 100 mặt hàng nghe có vẻ không phải là một con số lớn - tôi hy vọng bạn có thể tăng cao hơn thế rất nhiều. Hàng ngàn không phải là một vấn đề. Điều có thể là một vấn đề là tổng mức tiêu thụ bộ nhớ.


0

Tôi đã lấy một số tập dữ liệu khá lớn trong bộ nhớ một cách đáng xấu hổ, và thay vào đó, nó đã trở nên chậm chạp, có thể mất 15 Mo dữ liệu trở lên với các tính toán khá dữ dội trên tập dữ liệu. Tôi nghi ngờ bạn sẽ gặp vấn đề với bộ nhớ trừ khi bạn có những tính toán dữ dội trên dữ liệu và nhiều hàng. Lập hồ sơ và điểm chuẩn với các bộ kết quả giả khác nhau sẽ là cách tốt nhất để bạn đánh giá hiệu suất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.