ขนาดสูงสุดของ Array ใน Javascript


108

บริบท: ฉันกำลังสร้างไซต์เล็ก ๆ ที่อ่านฟีด rss และอัปเดต / ตรวจสอบฟีดในพื้นหลัง ฉันมีอาร์เรย์หนึ่งรายการเพื่อเก็บข้อมูลที่จะแสดงและอีกอาร์เรย์ที่เก็บ ID ของระเบียนที่แสดง

คำถาม: อาร์เรย์สามารถเก็บรายการใน Javascript ได้กี่รายการก่อนที่สิ่งต่างๆจะเริ่มช้าหรือเฉื่อยชา ฉันไม่ได้จัดเรียงอาร์เรย์ แต่กำลังใช้ฟังก์ชัน inArray ของ jQuery เพื่อทำการเปรียบเทียบ

เว็บไซต์จะถูกปล่อยให้ทำงานและอัปเดตและไม่น่าเป็นไปได้ที่เบราว์เซอร์จะถูกรีสตาร์ท / รีเฟรชบ่อยครั้ง

ถ้าฉันควรคิดเกี่ยวกับการล้างบางระเบียนออกจากอาร์เรย์วิธีใดคือวิธีที่ดีที่สุดในการลบบางระเบียนหลังจากขีด จำกัด เช่น 100 รายการ


3
คุณอาจประสบปัญหาเบราว์เซอร์รั่วหน่วยความจำจากแถบเครื่องมือมากกว่าจากรหัส JS :) Firefox 4 ฉันชี้นิ้วไปที่คุณ
epascarello

1
คุณตรวจสอบอาร์เรย์บ่อยเพียงใด (เช่นช่วงเวลา 2 วินาที) อะไรที่ทำให้เฉื่อยชา (เช่น> 500ms)? อาร์เรย์ของคุณมีลำดับขนาดเท่าใด (เช่นพันล้านพันล้าน)
zzzzBov

2
ทำการทดสอบ Benchmark กับjsperf.com
VirtualTroll

ฉันจะตรวจสอบและอัปเดตอาร์เรย์ทุกนาที และใช่ที่เฉื่อยชาจะเป็นผลกระทบด้านประสิทธิภาพที่เริ่มมีผลต่อการโหลดและตรวจสอบและภาพเคลื่อนไหวอื่น ๆ บนหน้านั้นยากที่จะกำหนดขออภัย!
addedlovely

@Amine ขอบคุณสำหรับลิงค์ดูเหมือนว่าเว็บไซต์นั้นจะเป็นเพื่อนที่ดีที่สุดของฉัน :)
addedlovely

คำตอบ:


153

ความยาวสูงสุดจนกว่า "มันจะอืด" ขึ้นอยู่กับเครื่องเป้าหมายและรหัสจริงของคุณโดยสิ้นเชิงดังนั้นคุณจะต้องทดสอบบนแพลตฟอร์มนั้นเพื่อดูว่าอะไรเป็นที่ยอมรับได้

อย่างไรก็ตามความยาวสูงสุดของอาร์เรย์ตาม-262 ECMA ข้อกำหนดฉบับที่ 5 ที่ถูกผูกไว้โดยไม่ได้ลงนามจำนวนเต็ม 32 บิตเนื่องจากการToUint32การดำเนินงานนามธรรมดังนั้นเป็นไปได้อาร์เรย์ที่ยาวที่สุดอาจมี 2 32 -1 = 4294967295 = 4290000000 องค์ประกอบ .


13
@ Barkermn01: ข้อกำหนด ECMA-262 5th Edition ใช้การดำเนินการนามธรรม ToUint32สำหรับการตรวจสอบความยาวของอาร์เรย์ในการดำเนินการใด ๆ ที่ปรับเปลี่ยนความยาวดังนั้นฉันคิดว่าสถาปัตยกรรมพื้นฐานของเครื่อง (หรือเว็บเบราว์เซอร์) ไม่เกี่ยวข้อง
maerics

1
hrm ดีแค่อ่านว่าเบราว์เซอร์ 64Bit ที่ยอดเยี่ยมตัวหนึ่งกำลังลุกเป็นไฟอย่างไร้จุดหมาย
Barkermn01

3
@ Barkermn01 เบราว์เซอร์ 64 บิตยังคงมีการปรับปรุงอื่น ๆ อีกมากมาย โปรดจำไว้ว่าการเป็นล่าม JavaScript ไม่ใช่สิ่งเดียวที่เบราว์เซอร์ทำ
Razor Storm

1
Wowzer ไม่คาดคิดว่ามันจะสูงขนาดนั้น โอเคดีฉันคิดว่าฉันจะสบายดี!
addedlovely

จริงๆแล้วอาร์เรย์สามารถมีองค์ประกอบได้สูงสุด 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
แนวคิดคือการใช้วงแหวนบัฟเฟอร์ใช่แล้ว - คุณจงใจ "ลืม" ข้อมูลเก่า (นั่นคือสิ่งที่ใช้สำหรับวงแหวนบัฟเฟอร์) และนั่นคือสิ่งที่ผู้ถามถาม
Lelanthran

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
จบลงด้วยการใช้ slice ตามที่ฉันต้องการเพื่อตัดแต่งจากจุดเริ่มต้นของอาร์เรย์ขอบคุณ
addedlovely

3

เช่นเดียวกับที่ @maerics กล่าวไว้เครื่องเป้าหมายและเบราว์เซอร์ของคุณจะกำหนดประสิทธิภาพ

แต่สำหรับตัวเลขในโลกแห่งความเป็นจริงบน Chromebook สำหรับองค์กรปี 2017 ของฉันกำลังเรียกใช้การดำเนินการ:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 ใช้เวลา 16ms ดีพอสำหรับ 60fps
  • x=4e6 ใช้เวลา 250ms ซึ่งเห็นได้ชัดเจน แต่ไม่ใช่เรื่องใหญ่
  • x=3e7 ใช้เวลา 1300ms ซึ่งค่อนข้างแย่
  • x=4e7 ใช้เวลา 11000ms และจัดสรรหน่วยความจำเพิ่มเติม 2.5GB

ดังนั้นประมาณ 30 ล้านองค์ประกอบจึงเป็นขีด จำกัด บนที่ยากเนื่องจาก javascript VM ตกจากหน้าผาที่ 40 ล้านองค์ประกอบและอาจทำให้กระบวนการขัดข้อง


2

ฉันได้สร้างกรอบประสิทธิภาพการทำงานที่จัดการและสร้างกราฟชุดข้อมูลหลายล้านชุดและถึงอย่างนั้นเวลาในการตอบสนองของการคำนวณจาวาสคริปต์ก็อยู่ในลำดับที่สิบมิลลิวินาที ถ้าคุณไม่กังวลว่าจะเกินขีด จำกัด ขนาดอาร์เรย์ฉันไม่คิดว่าคุณจะต้องกังวลมากนัก


0

มันจะขึ้นอยู่กับเบราว์เซอร์มาก 100 รายการไม่เหมือนจำนวนมาก - ฉันคาดว่าคุณจะไปได้สูงกว่านั้นมาก พันไม่น่าจะมีปัญหา สิ่งที่อาจเป็นปัญหาคือการใช้หน่วยความจำทั้งหมด


0

ฉันได้ดึงชุดข้อมูลขนาดใหญ่สวย ๆ ในหน่วยความจำอย่างไร้ยางอายและแม้ว่ามันจะเฉื่อยชา แต่ก็อาจต้องใช้ข้อมูล 15 Mo ขึ้นไปพร้อมกับการคำนวณที่ค่อนข้างเข้มข้นในชุดข้อมูล ฉันสงสัยว่าคุณจะประสบปัญหากับหน่วยความจำเว้นแต่คุณจะคำนวณข้อมูลอย่างเข้มข้นและมีแถวจำนวนมาก การสร้างโปรไฟล์และการเปรียบเทียบด้วยชุดผลลัพธ์จำลองที่แตกต่างกันจะเป็นทางออกที่ดีที่สุดของคุณในการประเมินประสิทธิภาพ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.