programing tip

ES6 템플릿 리터럴이 문자열 연결보다 빠릅니까?

itbloger 2020. 11. 21. 14:35
반응형

ES6 템플릿 리터럴이 문자열 연결보다 빠릅니까?


벤치 마크를 한 사람이 있습니까? HTML 생성 코드가 문자열 연결 또는 Node 및 최신 브라우저의 템플릿 리터럴을 사용하여 더 빠른지 궁금합니다.

예를 들면 :

문자열 연결

"<body>"+
  "<article>"+
    "<time datetime='" + date.toISOString() +"'>"+ date +"</time>"+
  "</article>"+
"</body>"

템플릿 리터럴

`<body>
  <article>
    <time datetime='${ date.toISOString() }'>${ date }</time>
  </article>
</body>`

순간 문자열 연결이 더 빠른 것 같습니다 : http://jsperf.com/es6-string-literals-vs-string-concatenation

ES6 with variable                     19,992,512    ±5.21%    78% slower
String concatenation with variable    89,791,408    ±2.15%    fastest
ES6 with function                     461,358       ±3.12%    99% slower
String concatenation with function    503,255       ±1.77%    99% slower

테스트는 #enable-javascript-harmony플래그가 활성화 된 V8 4.3.31을 사용하는 Chrome 43.0.2334.0 canary (64 비트)에서 실행되었습니다 .

참고로 Node.js의 최신 버전 (작성 당시 0.12.0)은 V8 3.28.73을 사용하고 있습니다 : https://raw.githubusercontent.com/joyent/node/master/ChangeLog

적용 할 수있는 가능한 모든 성능 최적화가 아직 적용되지 않았을 것이므로 ES6가 최종화에 가까워지고 이러한 기능이 안정 브랜치로 마이그레이션됨에 따라 성능이 향상 될 것으로 기대하는 것이 합리적입니다.


편집 : @ user1329482, @ icl7126, Nicolai Borisik 및 FesterCluck 의견에 감사드립니다. 이 질문을받은 지 약 2 년이 지났으므로 ES6 브라우저 지원이 크게 증가했으며 상당한 성능 최적화가 이루어졌습니다. 다음은 몇 가지 업데이트입니다.

Chrome (59.0.3035 기준)에서는 ES6 문자열 리터럴이 더 빠릅니다 .

ES6 with variable                     48,161,401       ±1.07%    fastest
String concatenation with variable    27,046,298       ±0.48%    44% slower
ES6 with function                     820,441          ±1.10%    98% slower
String concatenation with function    807,088          ±1.08%    98% slower

Firefox (57.0.0 기준)에서는 ES6 문자열 리터럴이 더 빠릅니다 .

ES6 with variable                     1,924,610,984    ±0.50%    fastest
String concatenation with variable    1,876,993,458    ±0.79%    3% slower
ES6 with function                     539,762          ±5.04%    100% slower
String concatenation with function    546,030          ±5.88%    100% slower

Safari (11.0.2 기준)에서는 다음 사항에 따라 다릅니다.

ES6 with variable                     1,382,752,744    ±0.71%    fastest
String concatenation with variable    1,355,512,037    ±0.70%    2% slower
ES6 with function                     876,516          ±1.01%    100% slower
String concatenation with function    883,370          ±0.79%    100% slower

타입 캐스트 문자열을 사용할 때 ES6 문자열 리터럴이 더 빠릅니다 . 그러나 리터럴에서 함수를 호출 할 때이 예제 에서는 문자열 연결이 더 빠릅니다 .

정말로 깊이 들어가서 Safari의 모든 성능 저하를 짜 내야한다면 문자 그대로 효과 성능 내에서 변수와 여러 참조를 잘못 입력했는지 여부를 확인하는 테스트를 설정하는 것이 좋습니다.


node.js v6.0.0 에서 순진한 테스트를 했고 거의 동일한 성능을 얻었 습니다 . 테스트가 너무 순진하기 때문에 숫자를 너무 많이 믿지 마십시오. 그러나 오늘날 JIT 컴파일러는 매우 최적화 된 코드를 생성하는 것 같습니다. 이를 통해 노드 앱에 대한 연결보다 템플릿을 선호하도록 결정할 수 있습니다.

참고로 이것은 내가 사용한 코드입니다.

'use strict'

function strConcat(i) {
    return 'abc' + i + 'def'
}

function strTemplate(i) {
    return `abc${i}def`
}

function run(strategy) {
    let before = new Date().getTime()
    let len = 0
    for ( let i = 0; i < 10000000; i+=1 ) {
        len += strategy(i).length
    }
    console.log(len + ' - ' + ((new Date().getTime()) - before) + 'ms')
}

console.log('strConcat')
run(strConcat)

console.log('strTemplate')
run(strTemplate)

결과는 다음과 같습니다.

strConcat
128888890 - 1904ms
strTemplate
128888890 - 1979ms

저는 len옵티마이 저가 전체 루프를 최적화하지 않도록 절대적으로 확인했습니다. 어쨌든 여전히 매우 간단한 테스트입니다. 누군가가 더 정교한 것을 만들 수있을 것입니다.


난수를 문자열로 사용하는 간단한 테스트의 경우 둘 다 Chrome 및 FF에서 매우 가깝습니다.

Chrome 58.0.3029 / Windows 10에서 테스트

문자열 리터럴 2,996,883 ± 2.36 % 가장 빠름

연산자 (+) 3,054,078 ± 2.01 % 가장 빠름

Concat 함수 2,659,391 ± 2.35 % 13 % 느림

Firefox 53.0.2 / Windows 10에서 테스트

문자열 리터럴 1,923,835 ± 1.52 % 가장 빠름

연산자 (+) 1,948,503 ± 1.13 % 가장 빠름

Concat 기능 1,810,857 ± 1.81 % 8 % 느림

여기 jsperf에서 테스트


TL; DR

연결 속도와 관련하여 더 빠르고 일관성이 있습니다. 그러나 변수 1 개 또는 2 개의 차이는 거의 없습니다 (1 억 호출의 경우 .3 초 미만).

편집하다

두 번째 실행 후 연결이 대부분 두 가지 중 더 빠른 것 같습니다.


그래서 저는 더 광범위하고 두 기능의 확장 성을 (조금) 살펴본 테스트를 제공하여 analog-nico의 답변 을 확장하고 싶었습니다 .

pastebin의 코드

각 함수에 대해 4 개의 테스트 케이스를 사용하기로 결정했습니다. 변수는 앞쪽에, 끝에 하나, 중간에 하나, 중간에 두 개 있습니다. 기본 설정은 동일합니다. 저는 함수의 100,000,000 반복을 사용하고 있으며 이러한 반복은 100 번 실행됩니다. 최적화를 방지하기 위해 동일한 메커니즘을 사용했습니다. 즉, 결과 문자열의 길이 합계를 가져와 로깅했습니다. 또한 필요한 시간을 기록했지만 (얼마나 걸릴지 추측하기 위해) 배열에 저장했습니다.

그 후 각 방법의 평균, 최소, 최대 및 표준 편차를 계산했습니다.

결과는 다음과 같습니다.

{ 
  sum: { 
    t: { 
      start: 2072751, 
      mid: 2338476, 
      end: 2083695, 
      double: 2950287 
    },
    c: { 
      start: 2086059, 
      mid: 2345551, 
      end: 2074732, 
      double: 2922929 
    } 
  },
  avg: { 
    t: { 
      start: 20727.51,
      mid: 23384.76,
      end: 20836.95,
      double: 29502.87 
    },
    c: { 
      start: 20860.59,
      mid: 23455.51,
      end: 20747.32,
      double: 29229.29 
    } 
  },
  sd: {
    t: {
      start: 335.6251329981114,
      mid: 282.9490809315344,
      end: 286.2220947096852,
      double: 216.40844045461824 
    },
    c: {
      start: 255.4803356424913,
      mid: 221.48744862858484,
      end: 238.98242111084238,
      double: 209.9309074433776 
    } 
  },
  min: { 
    t: { 
      start: 20490, 
      mid: 23216, 
      end: 20588, 
      double: 29271 
    },
    c: { 
      start: 20660, 
      mid: 23258, 
      end: 20534, 
      double: 28985 
    } 
  },
  max: { 
    t: { 
      start: 23279, 
      mid: 25616, 
      end: 22887, 
      double: 30843 
    },
    c: { 
      start: 22603, 
      mid: 25062, 
      end: 22403, 
      double: 30536 
    } 
  } 
}

t-objects의 값은 템플릿 용이고 c-objects의 값은 연결 용입니다. start변수가 시작 부분에 있고 중간에 있음을 의미하고 중간에 있음을 의미하며 끝이 끝에 있음을 의미하며 두 개의 변수가 있음을 의미합니다. sum100 회 실행의 합계입니다. avg평균 실행입니다 sum / 100. sd 여기에 쉬운 방법, wikipedia (simple english)가 있습니다. min그리고 max각각 실행의 최소 및 최대 값입니다.

결과

평균이 더 낮고 최소값이 더 낮다는 점을 고려할 때 문자열 끝에 위치하지 않는 단일 변수의 경우 템플릿이 더 빠릅니다. 문자열 끝에 변수를 넣거나 문자열에 여러 변수가 있으면 연결이 더 빠릅니다.

템플릿의 최소값과 평균이 처음 두 조건과 관련하여 연결 대응 항목보다 낫지 만 표준 편차는 지속적으로 더 나쁩니다. 변수가 많을수록 차이가 줄어드는 것 같습니다 (더 많은 테스트가 필요함).

대부분의 템플릿은 문자열에서 하나의 변수에만 사용되지 않을 것이므로 연결을 고수하면 더 나은 성능을 얻을 수 있습니다. 그러나 그 차이는 (적어도 현재로서는) 매우 미미합니다. 두 변수를 사용한 100,000,000 (1 억) 평가에서 차이는 약 1/4 초인 273,58ms에 불과합니다.


두 번째 실행

두 번째 실행은 다소 다르게 보입니다. 최대 값, 평균 절대 편차 및 표준 편차를 제외하고 모든 측정은 연결이 템플릿보다 빠르다는 것을 증명했습니다.

언급 된 세 개의 측정 값은 변수가 문자열의 끝에 있거나 문자열에 두 개의 변수가있을 때 템플릿에 대해 더 낮은 값을 가졌습니다.

결과는 다음과 같습니다.

{
  "sum": {
    "t": {
      "start": 1785103,
      "mid": 1826679,
      "end": 1719594,
      "double": 2110823,
      "many": 4153368
    },
    "c": {
      "start": 1720260,
      "mid": 1799579,
      "end": 1716883,
      "double": 2097473,
      "many": 3836265
    }
  },
  "avg": {
    "t": {
      "start": 17851.03,
      "mid": 18266.79,
      "end": 17195.94,
      "double": 21108.23,
      "many": 41533.68
    },
    "c": {
      "start": 17202.6,
      "mid": 17995.79,
      "end": 17168.83,
      "double": 20974.73,
      "many": 38362.65
    }
  },
  "sd": {
    "t": {
      "start": 858.7857061572462,
      "mid": 886.0941856823124,
      "end": 786.5366719994689,
      "double": 905.5376950188214,
      "many": 1744.9005638144542
    },
    "c": {
      "start": 599.0468429096342,
      "mid": 719.1084521127534,
      "end": 935.9367719563112,
      "double": 991.5642274204934,
      "many": 1465.1116774840066
    }
  },
  "aad": {
    "t": {
      "start": 579.1207999999996,
      "mid": 576.5628000000003,
      "end": 526.8268,
      "double": 586.9651999999998,
      "many": 1135.9432000000002
    },
    "c": {
      "start": 467.96399999999966,
      "mid": 443.09220000000016,
      "end": 551.1318000000008,
      "double": 610.2321999999999,
      "many": 1020.1310000000003
    }
  },
  "min": {
    "t": {
      "start": 16932,
      "mid": 17238,
      "end": 16387,
      "double": 20016,
      "many": 39327
    },
    "c": {
      "start": 16477,
      "mid": 17137,
      "end": 16226,
      "double": 19863,
      "many": 36424
    }
  },
  "max": {
    "t": {
      "start": 23310,
      "mid": 24102,
      "end": 21258,
      "double": 26883,
      "many": 49103
    },
    "c": {
      "start": 19328,
      "mid": 23203,
      "end": 22859,
      "double": 26875,
      "many": 44352
    }
  },
  "median": {
    "t": {
      "start": 17571,
      "mid": 18062,
      "end": 16974,
      "double": 20874,
      "many": 41171.5
    },
    "c": {
      "start": 16893.5,
      "mid": 18213,
      "end": 17016.5,
      "double": 20771,
      "many": 38849
    }
  }
}

코드는 여기에 있습니다


I think that the benchmark above is not useful. The result of interpolation or concatenation hasn't used. So yes, concatenation is pretty fast, because no string coping there and result string have only links to the parent strings. But if you'll try out the result string or compare with another one, the string will be serialized to plane string and, yes it will take some time. So interpolation could be more effective for CPU and memory usage then concatenation in real cases.

참고URL : https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation

반응형