Deep Dive 스터디 첫날, 조원인 두나님이 앞으로 스터디를 진행하면서 얻고자하는 것은 '기본기'라고 했다.
강사님은 본인이 생각하는 기본기란 '같은것을 구현할 수 있는 여러 방법 중 어떤것을 사용하는게 더 좋은지를 아는 것' 이라고 말씀하셨다.
예를들어, 자바스크립트에서 조건문을 표현 할 수 있는 방법은
삼항연산자와if...else문이 있다. 개발자의 입장에서는삼항연산자가 더 간결하기 때문에 좋은 코드라고 생각 할 수 있지만, 컴퓨터의 입장에서는if...else문이 더 나은 코드 일 수 있다.삼항연산자는 컨디션
?을 가지고 있기 때문에, 더 많은 CPU성능을 요구한다는 것이다.그러나
if...else문이 삼항연산자에 비해서 얼만큼 성능이 좋으냐 하면 CPU의 한칸의 공간만큼을 차지하고(사실 이부분은 CPU를 잘 몰라서 못 알아들었다.. 이후에 CPU 공간이라고 검색해봤는데도 못찾았다..) 0.1ms만큼 나은데, 이 수치가 유효한가를 따진다면 가독성을 위해서 이정도의 낭비는 포기할 수 있다는 것이다.중요한것은 이렇게까지 모든 코드의 성능을 알고 있어야 한다는게 아니라, 내가 이 코드를 사용하는 명확한 이유가 있어야 한다는 것이다.
이 후 스터디를 진행하면서 null vs undefined, if vs switch등 어떤 코드를 사용하는 것이 더 나은지에 대한 질문이 여러번 있었다.
그래서 성능을 체크할 수 있는 방법은 어떤 것이 있을까 하는 궁금증이 생겼고, 그 과정에 대해 포스팅 해보려 한다.
그러면 성능차이는 대체 어떻게 알 수 있을까? stackoverflow에 검색해봤다.
위 링크는, (stackoverflow에서 외부라이브언급으로 닫힌 질문이 된 것 같지만)
Benchmark.pm모듈을 사용하지않고 자바스크립트 자체에서 코드의 성능을 체크할 수 있는 방법이 뭐가 있는지에 대한 질문이었고,
Best 답변은 이러했다. console.time()을 사용하라.
이 외에도, 대부분의 답변이 성능체크를 위해서 시간을 측정하는 코드를 짜거나 횟수를 아주 많이 해야 한다는 답변이었다.
즉, 코드의 성능을 확인하려면 코드별로 많은 횟수를 실행하여 실행시간을 비교하라는 것이다.
mdn에서 console.time()메소드를 보면 설명은 위와 같다.
그래서 금주의 DeepDive스터디에서 공부한 주제인 암묵적형변환과 명시적형변환의 실행 시간을 체크해봤다.
function repeat(fn, num) {
let i = 0;
console.time('반복' + fn);
if (fn === 'ex') {
while (i < 10000) {
String(num);
i++;
}
} else if (fn === 'ex2') {
while (i < 10000) {
num.toString();
i++;
}
} else if (fn === 'in') {
while (i < 10000) {
num + '';
i++;
}
}
console.timeEnd('반복' + fn);
}
repeat('ex', 1000);
repeat('ex2', 1000);
repeat('in', 1000);
내가 실행한 테스트에서는 명시적형변환이 암시적형변환보다 더 오랜 시간이 걸렸고, 명시적형변환 중에서 빌트인생성자함수를 new없이 사용하는 방식이 더 오래걸렸다. 여러번 실행해봐도 마찬가지였다.
내가 실행한 방법이 맞는지 알 수 없어서 https://jsbench.me/ 에서 실행해보았다.

"ops/s"는 "Operations per second"의 약자로, 초당 수행되는 작업의 횟수이다. 결과를 보면, 나의 결과와도 달랐고, 데이터 타입마다 변환할 때 쓰이는 메소드에 따라서도 결과가 달랐다.
비슷하게 숫자의 형변환에 대해 포스팅한 블로그의 결과는 또 나와는 달랐다. parseInt가 더 느린 축에 속했다.
왜 이런 결과의 차이가 있는걸까?
이 글에 의하면, 사용되는 자바스크립트 엔진에 따라서 달라 질 수 있다고 한다. 크롬에서 toString()이 느린 이유는 V8 내부에서 C 함수에 대한 호출이 한 번 더 있기 때문이라고 한다.
5월11일 진행한 스터디에서 강사님께서 오픈소스라는게 있다는 것을 알려주셨다. 우리가 사용하는 코드는 모두 이렇게 설정되어있는걸 사용하는것이었다. 그래서 v8엔진의 오픈소스 깃허브를 들어가보았다.




솔직하게.. 오픈소스를 스스로 보는게 처음이고, 이게 어떤 언어인지 어떤 문법인지 거의 몰라서 제대로 파악을 할 수는 없었다.
toString을 검색해서 눈에익는 number-toString.js를 들어가보니, assertEquals라는 함수를 사용한다는것을 알게됐다. 깃헙에서는 assertEquals를 더블클릭하면 연관된 파일을 띄워준다.
그래서 assertEquals함수를 살펴보니, deepEquals함수의 결과를 받아서 객체나 배열의 깊은 내용까지 비교하여 동일하지 않으면 오류를 처리한다는걸 알게됐다.
deepEquals함수는 각 값의 type을 확인하여 결과에 따라서 return을 한다.
즉 toString()은 이렇게 내부적인 과정을 여러번 거쳐야 하기 때문에 v8엔진을 사용하는 브라우저에서는 다른 변환방법에 비해서 무거운 성능을 보여주게 되는 것 같고, 변환의 결과들도 모두 오픈소스에서 볼 수 있었다.
그래서 어떤 형변환 방법을 쓰는게 좋을까?
DeepDive 9장 초입에서는, 암묵적 타입 변환이 예측할 수 없다고 해서 반드시 명시적 타입 변환으로 코드를 작성하는것이 꼭 올바른 선택은 아니라고 한다. 때로는 가독성의 측면에서 암묵적 타입 변환이 더 나을 수도 있기 때문에 중요한 것은 나와 동료가 작성한 코드가 이해하기 쉽고 예측 가능해야 한다는 문장이 나온다.
나의 테스트들과 종합해보면 런타임 환경에 따라서 메소드들마다 구현된 방식이 다르고 또 어떤 데이터타입으로 변환하는지에 따라서도 차이가 있으니
나와 같은 공부를 하는 중인 입장에서 이것을 일일이 살펴보는것은 아직은 득보다는 실이 더 큰 일이라고 판단되며, 소통에 유리하며 예측가능하고 깔끔한 코드를 사용하는게 더 나을것 같다.
추가로 사실 유의미한 시간 차이는 구체적으로 얼만큼인가..? 하는 것을 알아야 할 것 같다. (못찾았다 ㅜ)
JSBench사이트에서 결과를 뽑아와도 이것이 맨처음에 언급한것처럼 무시해도 되는 정도인가? 하는 판단을 할 수가 없기 때문이다.