12. 벤치마킹과 튜닝

주요내용

벤치마킹(성능테스트)와 테스트 시나리오에 대한 간략한 내용이 대부분 그러면서 소개하는 Beanchmark.js jsPerf.com 사이트

테스트를 하는 항목외 부수효과가 발갱하는 부분을 잘 생각하고 설정해서 테스트를 해야한다 가 큰 맥락

테스트는 의도가 분명해야한다.. 당연한소리

Benchmark.js

벤치마킹 도구..? 테스트를 하도록 해주는 js 인듯 참고 : https://benchmarkjs.com/

  // 공식사이트 샘플 예제
  var suite = new Benchmark.Suite;

  // add tests
  suite.add('RegExp#test', function() {
    /o/.test('Hello World!');
  })
  .add('String#indexOf', function() {
    'Hello World!'.indexOf('o') > -1;
  })
  .add('String#match', function() {
    !!'Hello World!'.match(/o/);
  })
  // add listeners
  .on('cycle', function(event) {
    console.log(String(event.target));
  })
  .on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })
  // run async
  .run({ 'async': true });

jsPerf.com

다양한 환경에서 테스트를 할 수 있는 사이트라는데...?? 필요하면 사용하자 ㅋㅋ.. https://jsperf.com/

  // 케이스1
  var x = [];
  for (var i = 0; i < 10; i++) {
    x[i] = "x";
  }

  // 케이스2
  var y = [];
  for (var i = 0; i < 10; i++) {
    y[y.length] = "x";
  }

  // 케이스3
  var z = [];
  for (var i = 0; i < 10; i++) {
    z.push("x");
  }
  // 케이스1
  var x = false;
  var y = x ? 1 : 2;

  // 케이스2
  // var x; 이렇게 하지말 것 -> 이유는 상태조건이 다르다는것 세팅을하는 시간이 내포되어 있는점 감안해야한다는 내용
  var x = undefined;
  var y = x ? 1 : 2;

미세성능

성능에 지나친집착은 금물. 사소한 코드 하나하나에 집착하지 말것.. 부질없다

var foo = 41;
  (function () {
    (function () {
      (function (baz) {
        var bar = foo + baz;  // var bar = 41 + baz;  어떄 자명하자나... 응 아냐 렉시컬 스코프의 작동원리 때문 괜춘. 컴파일러가 보통 룩업 대상은 캐시해둬~
        console.log(bar);
      })(1);
    })();
  })();

  // factorial
  function factorial(n) {
    if (n < 2) {
      return 1;
    }
    return n * factorial(n - 1);
  }

  // 풀림재귀 코드 자바스크립트 엔진 (루프하나로 더 쉽게, 최적화 작업)
  function factorial(n) {
    if (n < 2) {
      return 1;
    }

    var res = 1;
    for (var i = n; i > 1; i--) {
      res *= i;
    }
    return res;
  }
  factorial(5); // 120, C 언어에서 이런 코드는 고급최적화 옵션을 주면 컴파일러가 상수값 120으로 대체하고 함수 정의, 호출코드를 날려버림

--i가 i++ 보다 빠르다는 사실은 일반적인 내용이긴하나. 자바스크립트의 엔진이 언제든지 i++를 ++i로 바꿀수 있는 상황은 존재하기때문에 무의미한 성능테스트라는데..

똑같은 엔진은 없다

브라우저마다 코드처리방식이 제각각. ES6 '꼬리호출 최적화'를 제외하면 자바스크립트 명세가 명시한 성능요건 같은건 없다.

v8 작동 원리를 최대한 활용한 코딩방식

  • 함수간에 arguments변수를 전달하지 말라. 누수때문에 함수 구현체가 느려짐.

  • try~catch 구문은 함수에서 떼어내라(분리). 브라우저가 try~catch 구문이 포함된 함수를 최적화하려고 해서 주변코드 반최적화됨?

문자열 join(), + 이야기 IE 쓰레기

꼬리호출 최적화(TCO)

스택프레임이 생성하냐 안하냐가 관건 진짜 꼬리호출일 때만 효과 ES6가 보증하는 기능이니 마음껏 써도 무방함! 일부 재귀패턴 구현 (func 기반)

  function foo(x) {
    return x;
  }

  function bar(y) {
    return foo(y + 1);  // 꼬리호출, 꼬리위치에서 호출 foo는 bar의 스택프레임을 재사용 
  }

  function baz() {
    return 1 + bar(40); // 꼬리호출x, 반환 후 1더하기 작업 때문에 호출스택을 쌓기 위해 별도의 메모리공간 할당필요
  }

Last updated