JavaScript의 반복문으로 for loop 문, forEach 메서드, map 메서드, reduce 메서드, $.each (Jquery) 등
정말 많은 종류의 반복문이 존재합니다.
비교 해볼 반복문
- for loop
- forEach
- map
- reduce
- $.each
속도 비교에 사용할 코드
const start = new Date()
... 실행 코드 ...
console.log((new Date() - start) / 1000)
먼저 비교 코드를 실행 전 시간을 저장한 다음에 비교할 코드를 실행, 그 후 현재의 시간과 코드를 시작한 시간을 비교하여 걸린 시간을 구할 수 있습니다.
코드가 끝난 시간 - 코드를 실행한 시간 수식을 사용하면 코드 실행에 걸린 밀리 초가 나오는데, 나누기 1000을 해주면 밀리초 단위를 초로 바꿀 수 있습니다.
for loop
const array = new Array(10000000).fill().map((v, i) => i)
const start = new Date()
let str = "";
for (let i = 0; i < array.length; i++) {
str += array[i]
}
console.log(new Date() - start)
// 결과 - 1291.1
단순한 연산 없이 반복문 만을 실행하는 것은 비교를 하는 의미가 없습니다. 가벼운 더하기 연산을 넣어주고, 10번을 돌려 평균값을 내었습니다.
forEach
const array = new Array(10000000).fill().map((v, i) => i)
const start = new Date()
let str = "";
array.forEach(v => {
str += v
});
console.log(new Date() - start)
// 결과 - 1385.8
결과를 보아하니 for 문보다는 느리지만 훨씬 가독성과 접근성이 좋다는 장점이 있는 forEach입니다.
map
const array = new Array(10000000).fill().map((v, i) => i)
const start = new Date()
let str = "";
array.map(v => {
str += v
});
console.log(new Date() - start)
// 결과 - 1458.2
for 문, forEach 보다는 느리지만 반환 값을 모아 새로운 배열을 반환하는 map은 forEach와 같이 많은 상황에서 필요로 합니다.
reduce
const array = new Array(10000000).fill().map((v, i) => i)
const start = new Date()
let str = "";
array.reduce((acc, v) => {
str += v
});
console.log(new Date() - start)
// 결과 - 1335.9
해당 글을 작성하기 위해 정보를 모으던 중 가장 충격받았던 부분이었습니다.
"바로 reduce가 forEach, map보다 빠르다..?"였습니다.
심지어 reduce의 누산 방식을 사용하면 for loop와 시간이 비슷하게 나왔습니다. (이유는 뒤에서)
$.each
const array = new Array(10000000).fill().map((v, i) => i)
const start = new Date()
let str = "";
$.each(array, (i, v) => {
str += v
});
console.log(new Date() - start)
// 결과 - 1971.3
재미로 Jquery에 있는 $.each 도 테스트해봤습니다.
reduce 정말 빠른가?...
이렇게 속도를 비교해도 결국 브라우저마다 성능 차이가 존재하며 반복문 안에서 어떤 코드를 쓰느냐에 따라 for 문이 더 느린 문법이 될 수도 있고 each가 가장 빠른 반복문이 될 수도 있습니다.
각 함수마다 고유의 기능을 가지고 있습니다. 예를 들어 find() 메서드는 특정 아이템을 찾을 때 용이하고, filter() 메서드는 여러 아이템을 찾을 때 용이합니다.
const array = new Array(10000000).fill(1);
const _for = [];
for (let i = 0; i < array.length; i++) {
_for.push(array[i] + 1);
}
// 1001
const forEach = [];
array.forEach((value) => forEach.push(value + 1));
// 1493
const reduce = array.reduce((acc, value) => {
acc.push(value + 1);
return acc;
}, []);
// 1483
const map = array.map((value) => value + 1);
// 1019
다음과 같이 +, -의 연산이 아닌 배열에서 값을 뽑아와 새로운 배열에 넣어주는 작업코드로 시간을 측정하면, for loop와 map 메서드는 속도가 비슷하고 forEach, reduce문은 상대적으로 속도가 훨씬 느리게 나오게 됩니다.
즉 reduce의 속도가 빠르게 나온것도 reduce의 기능인 누산 작업(+, - 기본 연산)을 이용해서 실험했기 때문입니다.
결론
브라우저에 따라 다른 기준이 나오겠지만, 크롬을 기준으로 [ for loop > reduce > foreach > map >>> $.each ]의 순으로 속도가 더 빠른 거 같습니다만.... 결국은 제대로 된 용도에 적절한 for loop, 고차함수를 사용이 중요한 것 같습니다.