자바스크립트 배열+반복문의 속도 테스트(map, for, while, for…in, for…of)

반복문의 배열 작업 속도를 확인하기

배열 관련하여 각 요소별로 순회하는 반복문 작업을 할 때 가장 익숙한 방법을 사용하거나 때로는 가장 먼저 떠오르는 방법을 사용하기도 합니다.

배열의 크기가 작으면 상관이 없지만 배열의 크기가 커지면 작은 차이가 큰 차이를 만들어낼 수 있습니다.

문득 연산 속도가 가장 빠른 반복문이 무엇일까라는 궁금증이 생겨 간단하게 하나의 배열 데이터를 다른 배열로 옮기는 연산을 통해 속도를 테스트해보고자 합니다.

크기에 상관없이 반복문 별로 같은 효율을 보여주리라 생각했지만 배열의 크기에 따라 각각 다른 속도를 보여주는 점이 흥미로웠습니다.


1. 테스트 방법

먼저 일정 크기를 갖는 배열 array을 생성합니다.

console.time 메서드를 사용해 이 배열의 데이터를 다른 배열로 복사하는 작업을 진행하고 이 작업 시간을 측정합니다.

테스트는 map, for, while, for…in, for…of의 다섯 가지 반복문을 사용합니다.

// 배열 데이터 생성
const array = [];
for(let i=0;i<10000;i++){
  array.push(i);
}

// 데이터가 복사될 배열
let arraymap = [];

console.time('map');  //타이머 시작
arraymap = array.map(list=>list);
console.timeEnd('map'); //타이머 종료

위와 같은 방식으로 3회씩 테스트를 진행하며 배열의 크기를 조절하여 반복문 별로 상대적인 작업 속도의 변화를 확인합니다.


2. 테스트

먼저 배열의 크기가 아주 작을 때는 모두 큰 차이를 보이지 않습니다.

다음은 배열의 크기가 100일 때 결과입니다.

작업을 세 번 진행한 결과 map과 for…of가 엎치락뒤치락하지만 항상 가장 빠른 속도를 보여줍니다.

for, while, for…in도 세번 모두 결과가 엎치락뒤치락하지만 위의 두 반복문보단 느린 속도를 보여줍니다.

그럼 배열의 크기를 1000으로 올려보겠습니다.

크기가 1000일 때는 대체적으로 비슷한 속도를 보여줍니다.

for…in만 다른 반복문보다 느린 것이 확인됩니다.

이제 확연하게 유의미한 차이를 느낄 수 있는 크기인 10000으로 올려보겠습니다.

10000에서는 map이 가장 우수한 속도를 보여줍니다.

눈에 띄는 부분은 작은 사이즈에서는 map과 대등한 속도를 보이던 for…of가 여기서는 가장 느린 속도를 기록합니다.

또한 for…in은 오히려 for…of보다 빠른 속도를 보여줍니다.

그럼 1000000으로 확인해 보겠습니다.

배열이 매우 커지니 작업 속도는 for문이 가장 준수합니다.

map, while도 큰 차이를 보이지 않고 준수한 성능을 보여줍니다.

for…of는 확연하게 조금 느린 속도를 보여주고 for…in은 이제 인사를 해야할 것 같습니다.

그럼 마지막으로 10000000(천만)으로 테스트를 해보겠습니다.

세 번 테스트한 결과 모두 for 문이 가장 빠른 속도를 보여주었으며, map, while도 의미있는 속도를 보여줍니다.

확실히 for…of는 위의 세 반복문보다 느린 속도를 보여주었으며 for…in은 10배가 넘는 느린 속도의 차이를 보여줍니다.


3. 결과 정리

배열 테이터의 크기가 작을 때는 의미있는 차이가 없지만 배열이 커질수록 map, for, while의 속도가 우수하고 for…in, for…of는 속도 저하를 보이는 결과를 나타냅니다.

어디까지나 단순한 작업인 배열 데이터 복사 기능만을 사용한 테스트이므로 작업 내용에 따라 다른 결과를 보일 가능성이 있어 단순 참고용으로 삼으면 좋을 것 같습니다.

다음은 테스트에 사용한 코드 전체입니다.

console.log('-------------start----------------')

const array = [];

for(let i=0;i<10000;i++){  //크기 변경
	array.push(i);
}

console.log("arraysize:"+array.length);
console.log('--------------------------------');

let arraymap = [];

console.log('arraymap start:'+arraymap.length);
console.time('map');

arraymap = array.map(list=>list);

console.log('arraymap end:'+arraymap.length);
console.timeEnd('map');
console.log('--------------------------------');


let arrayfor = [];
console.log('arrayfor start:'+arrayfor.length);
console.time('for');

for(let i=0; i<array.length;i++){
	arrayfor.push(array[i]);
};

console.log('arrayfor end:'+arrayfor.length);
console.timeEnd('for');
console.log('--------------------------------');

let arraywhile = [];
let whilenum = 0;
console.log('arraywhile start:'+arraywhile.length);
console.time('while');

while(whilenum<array.length){
	arraywhile.push(array[whilenum]);
	whilenum++;
};

console.log('arraywhile end:'+arraywhile.length);
console.timeEnd('while');
console.log('--------------------------------');

const arrayforof = [];
console.log('arrayforof start:'+arrayforof.length);
console.time('forof');

for(const num of array){
	arrayforof.push(num)
};

console.log('arrayfor end:'+arrayforof.length);
console.timeEnd('forof');
console.log('--------------------------------');

let arrayforin = [];
console.log('arrayforin start:'+arrayforin.length);
console.time('forin');

for(const num in array){
	arrayforin.push(array[num]);
};

console.log('arrayforin end:'+arrayforin.length);
console.timeEnd('forin');


console.log('---------------end-----------------');

자바스크립트, 편리한 배열 병합 방법(Merge Arrays in Javascript)

자바스크립트의 배열 병합 방법(concat(), …spread, push())

자바스크립트를 사용해 데이터를 다루는 일이 점점 더 많아지고, 배열을 사용하는 관련 작업을 많이 하게 됩니다.

그 중에서도 병합과 관련된 부분에 대해 알아보도록 하겠습니다.


배열은 인덱스(Index)를 갖는 요소를 순서대로 나타낸 데이터 구조입니다.

하나의 배열이라면 인덱스 또는 메소드(unshift(), push(), shift(), pop(), splice(), find(), includes(), join(), indexOf() 등)를 사용해 배열 내부의 데이터를 쉽게 다룰 수 있죠.

배열의 병합(Merge) 또한 마찬가지입니다.

concat(), push(), 스프레드 연산자(…spread), 등 배열의 병합을 위한 여러 방법이 존재합니다.

하나씩 확인해 보겠습니다.

1. 배열 병합의 3가지 방법

concatenate(연결시키다, 사슬같이 잇다)의 약자인 concat()은 말 그대로 두 배열을 연결하는 역할을 합니다.

크게 다음과 같은 방식으로 사용하며, 샘플 코드를 통해 조금 더 상세한 부분을 확인하겠습니다.

  • [array1].concat([array2]…..)
  • [].concat([array1], [array2]……)
const color1 = ['blue', 'pink', 'white'];
const color2 = ['black', 'orange', 'yellow'];
const num1 = [100, 200, 300];
const num2 = [400, 500, [600, 700]];

const allColor = color1.concat(color2); 
//['blue', 'pink', 'white', 'black', 'orange', 'yellow']
console.log(allColor); 

const colorPlus = color1.concat('gold', ['silver', 'bronze']); 
//['blue', 'pink', 'white', 'gold', 'silver', 'bronze']
console.log(colorPlus);

const colorAndNum = color1.concat(num1);   
//['blue', 'pink', 'white', 100, 200, 300]
console.log(colorAndNum); 

const allNum = num1.concat(num2);   
//[100, 200, 300, 400, 500, [600, 700]]
console.log(allNum); 

위와 같이 concat은 하나 이상의 배열을 합쳐 하나의 배열로 만듭니다.

배열 내부 데이터 타입에 상관없이 병합이 가능하며, 중첩된 배열의 병합도 가능합니다.

ES6에서 추가된 문법인 스프레드 연산자는 배열이나 객체를 빠르고 안전하게 복사할 수 있습니다.

깊은 복사(Deep copy) 방식으로 복사를 진행해 기존의 배열 데이터와는 다른 메모리 주소를 사용하므로 배열 병합 방법 중에서는 가장 좋은 방식이라고 볼 수 있습니다.

const musician = ['Chet Baker', 'Miles Davis'];
const actor = ['Clint Eastwood', 'George Clooney'];

const favorites = [...musician, ...actor];    
// ['Chet Baker', 'Miles Davis', 'Clint Eastwood', 'George Clooney'];
console.log(favorites); 

const favoritesReverse = [...actor, ...musician];
// ['Clint Eastwood', 'George Clooney', 'Chet Baker', 'Miles Davis'];
console.log(favoritesReverse)

스프레드 연산자는 다음과 같이 비구조화 할당에서도 자주 사용됩니다.

const myColor = ['beige', 'burgundy', 'charcoal', 'ivory'];

const [color1, color2, ...others  ] = myColor;
console.log(color1);   // 'beige'
console.log(color2);   // 'burgundy'
console.log(others);   // ['charcoal', 'ivory']

push() 메소드는 배열 끝에 데이터를 추가할 때 자주 사용하는 메소드입니다.

push() 메소드와 스프레드 연산자를 같이 사용하면 배열 병합이 가능하지만 기존 배열에 데이터를 추가하는 방식이므로 기존 배열이 변경되는 부분을 주의해야 합니다.

const pizza = ['dough', 'cheese', 'meat', 'source'];
const pizzaAdd = ['parmesan', 'tabasco'];

pizza.push(...pizzaAdd);   

// ['dough', 'cheese', 'meat', 'source', 'parmesan', 'tabasco'];
console.log(pizza); 

2. 마무리

배열을 병합하는 여러 가지 방법 중 concat(), …spread, push() 세 가지를 소개하였습니다.

각 상황에 따라 필요한 방법이 다르니 필요에 따라 맞는 것을 골라 사용하면 좋을 것 같습니다.

감사합니다!