javascript - Bir dizinin indekslerine değer atamadan önce uzunluğunu belirtmek daha mı verimli?


Değerleri atamadan önce dizinin uzunluğunu ayarlamanın herhangi bir faydası var mı?

Örneğin,

let arr = [];
arr.length = 10;
arr[0] = 'a'; // arr.length === 10
...
arr[9] = 'i'; // arr.length === 10

ya da hatta

let arr = new Array(10);
arr[0] = 'a'; // arr.length === 10
...
arr[9] = 'i'; // arr.length === 10

karşı

let arr = [];
arr[0] = 'a'; // arr.length === 1
arr[1] = 'b'; // arr.length === 2
...
arr[9] = 'i'; // arr.length === 10

Cevap #1

En azından V8'de, görünüyor ki new Array(length), alternatiflerden en az bir kat daha hızlıdır. Eğlence olsun diye push yöntemini de eklemek:

(uyarı: aşağıdaki kodu çalıştırmak tarayıcınızı bir süre engelleyecektir)

const t0 = performance.now();
for (let i = 0; i < 2e6; i++) {
  const arr = [];
  arr.length = 7;
  arr[0] = 'a';
  arr[1] = 'b';
  arr[2] = 'c'
  arr[3] = 'd'
  arr[4] = 'e'
  arr[5] = 'f';
  arr[6] = 'g';
}
const t1 = performance.now();
for (let i = 0; i < 2e6; i++) {
  const arr = new Array(7);
  arr[0] = 'a';
  arr[1] = 'b';
  arr[2] = 'c'
  arr[3] = 'd'
  arr[4] = 'e'
  arr[5] = 'f';
  arr[6] = 'g';
}
const t2 = performance.now();
for (let i = 0; i < 2e6; i++) {
  const arr = [];
  arr[0] = 'a';
  arr[1] = 'b';
  arr[2] = 'c'
  arr[3] = 'd'
  arr[4] = 'e'
  arr[5] = 'f';
  arr[6] = 'g';
}
const t3 = performance.now();
for (let i = 0; i < 2e6; i++) {
  const arr = [];
  arr.push('a');
  arr.push('b');
  arr.push('c');
  arr.push('d');
  arr.push('e');
  arr.push('f');
  arr.push('g');
}
const t4 = performance.now();

console.log('arr.length = length', t1 - t0);
console.log('new Array(length)', t2 - t1);
console.log('arr = [] only', t3 - t2);
console.log('push only', t4 - t3);

Fark Firefox'ta o kadar etkileyici değil, ama yine de mevcut - new Array(length) diğer seçeneklerden yaklaşık iki kat daha hızlı gibi görünüyor. Belki düşünebilirsiniz ki

const arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

daha da verimli olurdu, ki bu FF'de (birkaç kat daha fazla) doğrudur ama V8'de new Array(length) ile neredeyse aynı görünüyor:

const t0 = performance.now();
for (let i = 0; i < 2e8; i++) {
  const arr = new Array(7);
  arr[0] = 'a';
  arr[1] = 'b';
  arr[2] = 'c'
  arr[3] = 'd'
  arr[4] = 'e'
  arr[5] = 'f';
  arr[6] = 'g';
}
const t1 = performance.now();
for (let i = 0; i < 2e8; i++) {
  const arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
}
const t2 = performance.now();

console.log('new Array(length)', t1 - t0);
console.log(`arr = ['a', 'b', ...]`, t2 - t1);