2017-04-01 8 views
2

내 프로젝트의 JavaScript 코드 리팩토링 중 일부 루프가 크게 느려졌습니다. 루프 원인을 찾아서 this SO question이 슬로우 다운이 발생했습니다. 문 내에서 루프 및 클로저 생성이 발생했습니다. 도움이되지 않았다 for 루프 밖으로 let 및 폐쇄를 이동 놀랍게도 , 심지어 침체가 let에 의한for 루프 후 배치되어 있기 때문에 도움이되지 않습니다 또한 루프 변수 대신 letvar를 사용하여. 추가 세부 사항을 제거함으로써 나는이 코드를 획득했습니다 Javascript var vs v8 및 SpiderMonkey의 최적화/속도 저하 문제

"use strict" 
 
console.log("========================="); 
 
(function(){ 
 
    var itr = 0; 
 
    function f(){++itr;} 
 
    console.time('without_let'); 
 
    for(var i = 0; i < 50000000; ++i){ 
 
     f(); 
 
    } 
 
    var totals = 0; 
 
    console.timeEnd('without_let'); //chrome: 122ms, FF:102ms 
 
})(); 
 

 
(function(){ 
 
    var itr = 0; 
 
    function f(){++itr;} 
 
    console.time('let_below'); 
 
    for(var i = 0; i < 50000000; ++i){ 
 
     f(); 
 
    } 
 
    let totals = 0; // <--- notice let instead of var 
 
    console.timeEnd('let_below'); //chrome: 411ms, FF:99ms 
 
})(); 
 

 
(function(){ 
 
    let itr = 0; 
 
    function f(){++itr;} 
 
    console.time('let_above_and_in_loop'); 
 
    for(let i = 0; i < 50000000; ++i){ 
 
     f(); 
 
    } 
 
    var totals = 0; 
 
    console.timeEnd('let_above_and_in_loop'); //chrome: 153ms, FF:899ms 
 
})(); 
 

 
(function(){ 
 
    var itr = 0; 
 
    function f(){++itr;} 
 
    console.time('let_in_loop'); 
 
    for(let i = 0; i < 50000000; ++i){ 
 
     f(); 
 
    } 
 
    var totals = 0; 
 
\t \t console.timeEnd('let_in_loop'); //chrome: 137ms, FF:102ms 
 
})();
(또한 JS Fiddle 참고 : JS 바이올린을 사용하여 약간 다른 결과를 보여주고 있지만, 유사한 둔화는 여전히 같은 장소에 존재) 크롬에서이 작업을 실행

다음 생산하고

without_let: 122ms 
let_below: 411ms <----------- Slowdown for v8 
let_above_and_in_loop: 153ms 
let_in_loop: 137ms 

일부 인터넷 검색 결과 the article으로 이동하여 let이 Chrome 56/V8 5.6 이전에 최적화가 취소되었음을 알립니다! 내 크롬은 57.0.2987.133 (64 비트)이고 버전은 5.7.492.71입니다. 더 많은 놀라움이 Firefox 52.0.2 (32 비트)에서 실행하려고합니다. let로 만든 변수가 폐쇄 내부에서 사용하는 경우 여기에서 우리는 다른 곳에서 둔화가 :

without_let: 101.9ms 
let_below: 99ms 
let_above_and_in_loop: 899ms <----- Slowdown for SpiderMonkey 
let_in_loop: 102ms 

나는 문제가 다소 그래서 "임시 데드 존"기능이라고 관련,하지만 여전히 불분명있다시피 :

  1. 두 주요 브라우저 (주요 JavaScript 엔진)가 여전히 스 니펫의 해당 부분을 최적화 할 수없는 이유는 무엇입니까?

  2. let (제외) 바벨을 사용하여 var로 바꾸기위한 해결 방법이 있습니까? 크롬을 사용하도록 설정 한 후에 V8 버전 5.8.283.37 (https://omahaproxy.appspot.com/에 aconding를) correspondng, 58.0.3029.96 버전 크롬에서 : 나는 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);

UPD를 통해 V8로도 직접 크롬에 옵션을 전달하거나 할 수있어 가정 : // 플래그/# 가능-V8 - 미래를 jmrk 아래 세 번째 경우에 대한 둔화 (이제 2 번 대신 8 회)

without_let: 157.000ms 
let_below: 155.000ms 
let_above_and_in_loop: 304.000ms 
let_in_loop: 201.000ms 

파이어 폭스 53.0 (32 비트)

이 제안
+1

그들은 * 할 수 없다는 것이 아니라, 아직 구현할 시간을 찾지 못했습니다. 우선 순위를 정하기 위해 몇 가지 버그 보고서를 제출할 수 있습니다. – Bergi

+1

v8 https://bugs.chromium.org/p/v8/issues/detail?id=6188 에 대한 보고서 및 FF https://support.mozilla.org/en-US/questions/1158956 –

+1

에 대한 보고서입니다. 또한 Bugzilla 항목입니다. https://bugzilla.mozilla.org/show_bug.cgi?id=1362930 –

답변

2

질문의 V8 부분에 답변 할 수 있습니다. 당신이보고있는 속도 저하는 오래된 최적화 컴파일러 ("크랭크 샤프트"로 알려짐)의 한계로 인한 것입니다. 이 팀은 Chrome 59에서 제공되는 새로운 최적화 컴파일러 ("Turbofan") (현재 베타 버전의 Canary 및 Dev 채널에 있습니다!) 작업에 바빴 기 때문에이 모든 시간에 해결되지 않았습니다.

Chrome 58 (현재 베타)에서는 'Experimental JavaScript Compilation Pipeline'을 '사용함'(chrome://flags/#enable-v8-future)으로 설정하여 미리 볼 수 있습니다. Chrome 59에는 두 가지 추가 성능 향상 기능이 있습니다.

사이드 노트 : 기존 코드베이스에서는 let으로 마이그레이션 할 때 많은 이점이 없으므로 var을 계속 사용하면됩니다.

+0

Chrome 버전 58.0.3029.96에서이를 테스트했습니다. 최적화를 통해 과감한 속도 저하가 제거되었지만 여전히 세 번째 경우는 거의 두 배 느립니다. –