티스토리 뷰

반응형

Javascript에서는 변수를 선언하는 세 가지 키워드가 있다. 고전 JS부터 이어진 var와, ES6에서 새로 도입된 키워드 const, let이 있다. 현재 많은 JS 개발자들이 var 대신 const, let을 권장하고 있지만, 아직 많은 고전 JS 코드에서 var를 사용하는 경우도 많다.

 

임의의 변수를 let과 const로 선언할 경우 var보다 많은 장점이 존재한다. 예를 들어, 호이스팅 문제에서 자유롭거나, 중복된 변수 방지 등등 활용할 수 있다. var, let, const을 비교한 글은 여러 블로그에서 찾을 수 있으니, 구글에서 이에 대하여 검색하면 쉽게 얻을 수 있다. (만약 귀찮다면, 다음 글을 참고하면 된다.)

 

그러면, var가 let과 const를 사용하는 경우보다 나은 경우가 존재할까? 아니면  let과 const가 var에 비해 수행 시간에서 더 좋은 성능을 항상 내는 것일까? 이에 대하여 알아보도록 하자.

 

var, let, const의 성능 차이는 존재하는가?


1. 직접 실험해보자.

JS는 고수준(High-level) 인터프리터 언어이다. 즉, 직접 메모리 할당 및 메모리 반납을 하지 않아도 자동으로 메모리를 할당해주거나, GC(garbage collection)를 통해 메모리를 해제한다. JS도 같은 과정을 거친다. 변수를 사용할 때 메모리를 할당하고, 메모리를 사용하고, 사용하지 않을 때 메모리를 반환한다. 그러나, 사용자는 JS가 어떤 메모리를 사용할 지 직접 제어하진 못하고, JS가 자동으로 메모리를 할당하고 반환하도록 '유도'해야 한다.

 

var은 global-scope로 호이스팅이 발생하고, let과 const는 block-scope로 호이스팅이 발생하기에, JS 엔진이 변수를 인식하는 시점이 다르다. var의 경우 코드의 최상단 위로 호이스팅되어 코드의 맨 위에서 인식이 되지만, let과 const는 해당 변수가 선언된 곳 block 최상단에서 발견된다. 그러면, 이러한 시차는 큰 차이를 만들어내는가?

 

이에 대한 실험 코드를 작성하여 보자. const는 var과 다른 성격을 띄고 있고, const로 선언된 변수는 read-only 개념이 추가되기에 비교가 부적절하다고 생각한다. 따라서, let과 var를 중심으로 작성하겠다.

 

여러 기술 블로그에서 var 대신 let을 사용하라는 예제 코드는 보통 for-loop에서의 변수 선언이다. 

 

1
2
3
4
5
6
7
8
9
10
// using var
for (var i = 0; i < 1000; i++) {
    do_something(i);
}
 
 
// using let
for (let i = 0; i < 1000; i++) {
    do_something(i);
}
cs

 

보통 var대신 let을 사용하는 이유로 코드의 가독성과 변수 선언 실수 방지를 위하여 사용하라고 한다. 이에 대하여 수행 시간 차이는 있는가?

 

위의 for-loop의 수행 시간을 측정하여, 평균적인 수행 시간을 벤치마킹하자. 벤치마킹 코드는 이 링크를 참고하였다. 이를 서로 다른 2개 엔진(V8, SpiderMonkey)에서 실행하여보자. V8엔진의 경우 NodeJS, SpiderMonkey엔진의 경우 Firefox에서 실행하였다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const maxTests = 1000;
const loopLimit = 1000000;
const expectedX = 499999500000;
 
function test(index = 1, results = { usingVar: 0, usingLet: 0 }) {
  console.log(`Running Test #${index} of ${maxTests}`);
 
  setTimeout(() => {
    const varTime = usingVar();
    const letTime = usingLet();
    results.usingVar += varTime;
    results.usingLet += letTime;
 
    console.log(`Test ${index}: var = ${varTime}ms, let = ${letTime}ms`);
 
    ++index;
    if (index <= maxTests) {
      setTimeout(() => test(index, results), 0);
    } else {
      console.log(
        `Average time with var: ${(results.usingVar / maxTests).toFixed(2)}ms`
      );
      console.log(
        `Average time with let: ${(results.usingLet / maxTests).toFixed(2)}ms`
      );
    }
  }, 0);
}
 
function usingVar() {
  const start = Date.now();
  let x = 0;
  for (var i = 0; i < loopLimit; i++) {
    x += i;
  }
  if (x !== expectedX) {
    throw new Error("Error in test");
  }
  return Date.now() - start;
}
 
function usingLet() {
  const start = Date.now();
  let x = 0;
  for (let i = 0; i < loopLimit; i++) {
    x += i;
  }
  if (x !== expectedX) {
    throw new Error("Error in test");
  }
  return Date.now() - start;
}
 
test();
cs

 

이에 대한 실행 결과는 다음과 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1. V8(NodeJS), 1000 tests
Running Test #1 of 1000
Test 1: var = 10ms, let = 12ms
Running Test #2 of 1000
Test 2: var = 6ms, let = 4ms
...
Running Test #999 of 1000
Test 999: var = 2ms, let = 5ms
Running Test #1000 of 1000
Test 1000: var = 2ms, let = 2ms
 
Average time with var: 3.06ms
Average time with let: 2.76ms
 
 
2. SpiderMonkey(FireFox), 100 tests
Running Test #1 of 100
Test 1: var = 134ms, let = 125ms
Running Test #2 of 100
Test 2: var = 138ms, let = 163ms
...
Running Test #99 of 100
Test 99: var = 145ms, let = 138ms
Running Test #100 of 100 
Test 100: var = 136ms, let = 133ms
 
Average time with var: 146.66ms
Average time with let: 137.88ms
cs

 

결과적으로, let이 var보다 더 빠르다. 다만, 그 차이는 유의미할 정도의 차이가 아니다. (V8엔진의 경우 10%, SpiderMonkey엔진의 경우 6% 더 빠르다.)

 

왜 이런 결과가 생성될까? let은 각 for-loop마다 새로운 변수(i)를 생성해야 하지만, var는 호이스팅이 발생하기에 let이 최적화 할 수 있는 경우의 수가 많아진다. 현재 평균적인 loop 시간은 엇비슷한 것으로 보아, var과 let에는 수행시간 차이가 거의 없거나, 엔진이 직접 이에 대하여 최적화를 하였다고 결론을 지을 수 밖에 없다. 또한, 다른 함수로 테스트를 하여도 엇비슷한 결과를 얻었다. (적어도 V8엔진과 SpiderMonkey에서 말이다.)

 

따라서, 똑똑한 엔진이 var이든, let이든 이에 대하여 알아서 최적화 한다고 예상할 수 있다. 시간 문제가 있다면, 그건 var를 let이나 const를 쓰거나 그 반대의 경우가 아닌, 다른 문제일 가능성이 높으니까 마음놓고 let과 const를 쓰자!

 

2. 세 줄 요약

  1. var이나
  2. let, const나
  3. 성능 면에선 의미 없다.
반응형
댓글
Total
Today
Yesterday
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함