[JS] 반복문들의 성능 체크
안녕하세요! aloveu입니다.
얼마 전 Map, Set의 성능 체크를 하고서 뭔가 신선한 충격을 받았어요.
보지 않으셨다면?? https://aloveu.tistory.com/86 읽어보고 오시는 걸 추천드립니다. ㅎㅎ
오래된 개발자의 고정관념에서 나온 그런 충격이었는데 사실 이쪽 IT업계는 변화가 정말 엄청나니 언제든 바뀔 수 있는 결과였죠.
그래서 생각난김에 javascript에서 쓰이는 Array 메서드들의 성능을 다시 한번 체크해 보는 시간을 가져봤습니다.
오늘 테스트할 메서드는 이것도 얼마전에 포스팅을 했던 실무에서 꼭 필요한 Array 메서드라는 포스팅을 참고할 거예요.
[JS] 실무에서 꼭 필요한 Array 메서드
안녕하세요! aloveu입니다. 오늘은 이것만 알아도 데이터 바인딩 50%는 먹고 간다고 말할 수 있는 Array 메서드들에 대해서 공부해 볼 겁니다. 게시판, 상품, 방명록이나 댓글 같은 리스트 형식의 API
aloveu.tistory.com
단순 반복 비교 for vs forEach
// 큰 배열 생성
const arr = Array.from({ length: 10000000 }, (_, i) => i);
console.time('for loop');
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
console.timeEnd('for loop');
console.time('forEach');
let sum2 = 0;
arr.forEach(num => sum2 += num);
console.timeEnd('forEach');
단순 반복문을 돌리는 for문과 forEach를 비교해 봤습니다.
일반적으로 for 문이 forEach보다 조금 더 빠르다고 알려져 있는데 이건 예상을 벗어나지 않아서 조금 실망스럽네요 ㅋㅋㅋ
이 성능차이가 나는 이유는 forEach는 내부적으로 다른 함수를 호출하기 때문입니다.
조건 비교 for vs some vs every
이번에는 어떤 조건을 만족하는지에 대한 테스트를 해볼게요.
for문과 하나라도 조건이 만족하는지 체크하는 some, 모두 조건을 만족하는지 체크하는 every를 비교해 보겠습니다.
// 큰 배열 생성
const arr = Array.from({ length: 10000000 }, (_, i) => i);
console.time('for loop');
let found = false;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > 5000000) {
found = true;
break;
}
}
console.timeEnd('for loop');
console.time('some');
const hasBigNumber = arr.some(num => num > 5000000);
console.timeEnd('some');
console.time('every');
const allPositive = arr.every(num => num >= 0);
console.timeEnd('every');
어느 정도나 차이 나는지 테스트를 해보는 건데 이건 생각보다 많이 차이가 나네요.
every 같은 경우 모든 배열을 돌아야 하기 때문에 오래 걸릴 건 알았지만 some은 for문과 6배 가까이 차이 날 줄은 몰랐습니다.
다른 메서드들은 예상대로 for문이 압도적으로 빠릅니다.
누산 비교 for vs reduce
배열을 돌면서 어떤 값을 계속 더하는 테스트를 해봤습니다.
전부 위에 쓴 글처럼 for문을 승자로 처리하고 종료할까 하다가 이걸 따로 쓰는 이유는 의외로 reduce가 빨랐기 때문입니다.
// 큰 배열 생성
const arr = Array.from({ length: 10000000 }, (_, i) => i);
console.time('for loop');
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
console.timeEnd('for loop');
console.time('reduce');
const sum2 = arr.reduce((acc, curr) => acc + curr, 0);
console.timeEnd('reduce');
위의 코드는 천만이라는 숫자를 돌면서 값을 더하는 코드입니다.
리듀스가 더 빨라서 이번 포스팅도 성공한 듯 싶습니다. 하나 건졌어요.ㅋㅋㅋㅋㅋㅋ
정렬 비교 for vs sort
정렬은 제가 for문으로 정렬로직을 구현하는 게 미흡했을 수 있지만 압도적으로 sort 메서드가 빨랐습니다.
// 큰 배열 생성
const arr = Array.from({ length: 1000000 }, () => Math.floor(Math.random() * 1000000));
console.time('for loop');
const sorted = [...arr];
for (let i = 0; i < sorted.length; i++) {
let minIndex = i;
for (let j = i + 1; j < sorted.length; j++) {
if (sorted[j] < sorted[minIndex]) {
minIndex = j;
}
}
[sorted[i], sorted[minIndex]] = [sorted[minIndex], sorted[i]];
}
console.timeEnd('for loop');
console.time('sort');
const sorted2 = arr.slice().sort((a, b) => a - b);
console.timeEnd('sort');
왜 이런 압도적인 차이가 발생했을까요?? sort는 약간 특수합니다.
그건 정렬 알고리즘때문인데 제가 쓴 코드는 단순한 선택정렬이였다면 sort메서드는 저보다 훨씬 똑똑한 전문가들이 복잡하고 효율적인 알고리즘을 사용해 최적화 했기 때문입니다.
조금 더 간단한 정렬을 직접 구현했다면 for문이 빨랐을 수 있겠지만 거의 대부분의 정렬은 내장함수를 쓰시는게 훨씬 좋습니다.
결과
이 포스팅은 단순 속도 비교라서 some, every, forEach 같은 편리한 Array 메서드들이 있는데도 불구하고 안 쓰고 직접 구현하는 걸 추천하지 않습니다.
성능문제가 크게 필요하지 않은 대부분의 프로젝트라면 가독성과 유지보수성도 중요하기 때문에 기본적으로 제공해 주는 이런 메서드들을 써도 큰 문제가 없을 걸로 보여요.
그럼 오늘도 읽어주셔서 감사합니다. ^___^
'IT > 개발' 카테고리의 다른 글
3rd Party Cookie 차단?? (42) | 2024.06.11 |
---|---|
[CSS] Cascade Layers 정리 (93) | 2024.05.13 |
[JS] Map(), Set()의 이상한 성능테스트 (60) | 2024.05.07 |
[CSS] 버튼을 누를 때 폭죽 터지는 animation을 넣어보기 (136) | 2024.04.29 |
[NPM] Axios Error (38) | 2024.04.23 |