익명함수와 명명함수의 성능차이.
const test = () => {}
console.time('a');
for(let i =0; i < 1000000; i++) [1].some(test)
console.timeEnd('a');
console.time('b');
for(let i =0; i < 1000000; i++)[1].some(()=>{})
console.timeEnd('b');
자 일단 위의 코드를 보자. 어떤게 빠를까? 사실 이 코드를 작성하면서 a가 더 빠르겟지 라는 별생각 없이 작성하기는 하였다.
실제로는 b가 더 빠른 것이 확인 되었다.
a: 10.313232421875 ms
b: 2.833251953125 ms
위와 같은 결과가 나오자, 명명 함수를 참조하는 데에 오버헤드가 발생할 것이라 생각했다. 하지만, b의 경우 매번 새로운 함수를 생성하고 있지 않은가?
일단 이것이 착시이긴 하다. b의 경우 "() => {}"를 매번 생성하는 것이 아닌, 메모리에 생성 후 참조 하게 된다. 즉 생성은 한번만 하게 된다.
물론 명명함수도 메모리에 저장될 것이다. 하지만, 명명함수의 경우 "이름 => 참조 메모리" 단계가 포함이 되어있다.
const test = function() {}
const foo = () => {}
console.time('a');
for(let i =0; i < 10000000; i++) test(foo)
console.timeEnd('a');
console.time('b');
for(let i =0; i < 10000000; i++) test(() => {})
console.timeEnd('b');
a: 4.385986328125 ms
b: 13.735107421875 ms
자 이 상황은 대체 뭘까? 위의 결과와 완전 반대의 결과가 나왔다.
자, 한 번 테스트한 결과는 이거
1. [1].some(() => {})
4. test(() => {})
처음에 이야기한, 익명 함수가 한번 생성 된 다던가, 명명함수를 찾는데 추가적인 오버헤드가 있다던가 한다면,
test(foo)가 더 빨라야 한다.... 즉 최적화 되는 규칙이 조금 줏대가 없다... 아마 Array.prototype.some의 경우, callback함수를 제어하지 않기 때문에, 최적화의 여지가 더 있어서, 더 빠르게 나온 것 같기도 하다.
댓글
댓글 쓰기