2012-01-28 2 views
9

자바 스크립트가 어디 에나 있으며 내 마음에 끊임없이 중요성이 커지고 있습니다. 대부분의 프로그래머들은 Javascript 자체가 추악하지만 그 "영역"은 확실히 인상적이라는 것에 동의 할 것입니다. HTML5의 기능과 Javascript를 통해 애플리케이션을 배포하는 최신 브라우저의 속도는 흥미로운 옵션입니다. 아마도 당신이 얻을 수있는 크로스 플랫폼 일 것입니다.은 자바 스크립트보다 coffeescript가 빠릅니까?

자연스러운 결과는 크로스 컴파일러입니다. 우위는 아마도 GWT 일 것입니다.하지만 몇 가지 다른 옵션이 있습니다. Javascript에 비해 얇은 레이어를 추가하고 GWT보다 훨씬 가벼운 Coffeescript가 가장 좋습니다.

저를 괴롭히는 한 가지 사실이 있습니다. 프로젝트의 규모는 작지만 항상 중요한 주제였습니다. 견적은 여기

GWT SDK는 일련의 핵심 Java API 및 위젯을 제공합니다. 자바에서 AJAX 응용 프로그램을 작성하고, 너무 높은

이 커피 스크립트 최적화되어 자바 스크립트를 최적화 에 소스를 컴파일 할 이 허용? Coffeescript는 비 일반적인 자바 스크립트 기능을 많이 사용하는 것으로 보이기 때문에 성능이 어떻게 비교되는지 걱정됩니다.

Coffeescript 관련 속도 문제가 발생 했습니까? 좋은 벤치 마크 비교를 알고 계십니까?

+3

CoffeeScript는 비표준 기능을 사용합니까? –

+13

"JavaScript 자체가 추악합니다"-> false. – Raynos

+3

나는 Raynos에 동의한다. 나쁜 코드는 나쁜 코드이고, 어떤 언어로도 쓸 수있다. – calvinf

답변

37

오래된 주제를 부활시키려는 사과는 나에 관한 것이 었습니다. 나는 약간의 테스트를 수행하기로 결정했다. 그리고 내가 아는 가장 간단한 성능 테스트 중 하나는 배열에 연속적인 값을 쓰고, 배열이 커지면서 익숙한 방식으로 메모리를 소비하며, 'for'루프는 실제 생활에서 충분히 공통적으로 고려해야한다는 것이다. 관련된. 붉은 청어 몇 후

나는 커피 스크립트의 가장 간단한 방법은 찾을 수 :

newway = -> [0..1000000] 
# simpler and quicker than the example from http://coffeescript.org/#loops 
# countdown = (num for num in [10..1]) 

이것은 클로저를 사용하고 결과로 배열을 반환합니다. 나의 동등 물은 이것이다 :

당신이 볼 수 있던 결과는 동일 하 그것과 유사한 방법으로 너무 배열을 성장한다. 다음으로 나는 각각 100 번 크롬으로 프로파일을 만들고 평균을 냈습니다.

newway() | 78.5ms 
oldway() | 49.9ms 

커피점이 78 % 더 느립니다. 나는 (Jeremy Ashkenas)


부록 "당신이 쓰는 커피 스크립트 (그리고보다 더 자주 더 빠르게) 당신이 쓴 것 JS만큼 빠르게 실행 끝"고 반박 : 나는 "또한 대중적인 믿음을 의심했다가 JS에서 항상 일대일로 동일합니다. " 나는이 내 자신의 코드를 다시 시도 :

badway = -> 
    a = [] 
    for i in [1..1000000] 
     a[i] = i 
    return a 

을가 직선 번역하지 의미가 방향 (증가 또는 감소)에 대한 추가 검사를 추가하기 때문에 여전히 7 % 느리게 입증 유사성에도 불구하고.

+5

흥미로운 대답을 사과하는 이유는 무엇입니까? 나는 큰 차이를 기대하지 않았을 것이다. 물론 0에서 1000000까지의 모든 숫자를 배열에 추가하는 것은 일반적인 사용 사례가 아니며 하나의 브라우저 만 살펴 보았다고 말할 수 있습니다. 그러나 78 %!? 그건 힘들어요 +1 – lhk

+0

저자가 커피에서 생성 된 js의 문제를 측정하고 지적하는데 시간이 걸리기 때문에 이것은 답이되어야합니다. 커피를 사용하는 유일한 이유는 모두 생산성에 관한 것입니다. – nXqd

+0

클로저는 종종 Javascript에서 성능 저하로보고됩니다. Coffeescript는 절대적으로 필요하지 않은 곳에서도 광범위하게 사용합니다. – relet

8

Coffescript는 JavaScript로 직접 컴파일됩니다. 즉, Coffeescript 소스에 대해 JS에 항상 1 : 1로 상응합니다. 그것에 대해 비 공통적 인 것은 없습니다. 성능 향상은 최적화 된 방식으로 이루어질 수 있습니다. Coffescript가 모든 반복에서 그것을 요구하는 대신 for 루프의 별도 변수에 배열 길이를 저장한다는 사실. 하지만 JavaScript에서 일반적인 관행이되어야합니다. 언어 자체만으로는 적용되지 않습니다.

+1

좋은 답변입니다. JS CoffeeScript가 생성하는 것이 개발자가 그렇지 않은 것보다 더 똑똑하다면 퍼포먼스 이득이 될 것 같아요 ... 내가 추측하고있는 것은 드문 일이 아닙니다 –

+0

모범 사례를 통합하는 새로운 언어를 만드는 것이 좋습니다. 내가 보는 문제는 너무 화려 해 지려고 할 때입니다. 그리고 CoffeeScript가 왜 JS를 생성하는지 모든 사람들이 알 수 있습니다. – Daff

+0

@AdamRackis CoffeeScript가 평균적으로 악성 JavaScript를 생성하고 평균 개발자가 작성할 수 있습니다. 운이 좋으면 CS가 똥 개발자를 위해 더 나은 JavaScript를 생성하지만 개발자가 있다면 큰 문제가 있음을 알 수 있습니다. – Raynos

11

짧은 대답 : 아니요.

CoffeeScript는 자바 스크립트를 생성하므로 가능한 최대 속도는 자바 스크립트의 속도와 같습니다. 하지만 낮은 수준의 (예, 아이러니하게 들립니다.)에서 js 코드를 최적화하고 성능을 향상시킬 수 있지만 CoffeeScript로는 할 수 없습니다.

하지만 JS를 통한 CS 선택시 코드 속도가 중요하지 않습니다. 차이점은 대부분의 작업에서는 무시할 수 있습니다.

21

이것은 모두 매우 복잡하며 하나의 진실이 있습니다. 커피 스크립트는 완벽하게 최적화 된 자바 스크립트보다 빠르게 작동하지 않습니다.

즉, 커피 스크립트는 javascript를 생성하기 때문에. 그만한 가치가있는 방법이 있습니다. 슬프게도, 아직 그럴 것 같지 않습니다.

그것은 커피 스크립트 1.6.2

// Generated by CoffeeScript 1.6.2 
(function() { 
    var new_way; 

    new_way = function() { 
    var _i, _results; 

    return (function() { 
     _results = []; 
     for (_i = 0; _i <= 1000000; _i++){ _results.push(_i); } 
     return _results; 
    }).apply(this); 
    }; 

    new_way(); 

}).call(this); 

그리고 clockworkgeek에서 제공하는 코드와이로 컴파일

new_way = -> [0..1000000] 
new_way() 

function oldway() 
{ 
    var a = []; 
    for (var i = 0; i <= 1000000; i++) 
     a[i] = i; 
    return a; 
} 
oldway() 

그러나 이후입니다 :

는 예를 취할 수 있습니다 coffee 스크립트는 범위 내에서 함수를 숨기고, 우리는 자바 스크립트에서도 그렇게해야합니다. 우린 바로 창문을 드러내고 싶지 않아?

(function() { 
    function oldway() 
    { 
     var a = []; 
     for (var i = 0; i <= 1000000; i++) 
      a[i] = i; 
     return a; 
    } 
    oldway() 
}).call(this); 

그래서 여기에는 실제로 동일한 작업을 수행하는 코드가 있습니다. 그리고 나서 두 버전을 실제로 테스트 해보고 싶습니다.

커피 스크립트

for i in [0..100] 
    new_way = -> [0..1000000] 
    new_way() 

는 JS 생성, 그리고 당신이 거기에 무슨 일이 일어나고 있는지 자신을 요청할 수 있습니다 ??? 어떠한 이유로 든 i_i을 생성합니다. 이 두 가지로부터 나에게 분명합니다. 오직 하나만 필요합니다.

// Generated by CoffeeScript 1.6.2 
(function() { 
    var i, new_way, _i; 

    for (i = _i = 0; _i <= 100; i = ++_i) { 
    new_way = function() { 
     var _j, _results; 

     return (function() { 
     _results = []; 
     for (_j = 0; _j <= 1000000; _j++){ _results.push(_j); } 
     return _results; 
     }).apply(this); 
    }; 
    new_way(); 
    } 

}).call(this); 

그럼 이제 자바 스크립트를 업데이트 할 예정입니다. 그래서

(function() { 
    function oldway() 
    { 
     var a = []; 
     for (var i = 0; i <= 1000000; i++) 
      a[i] = i; 
     return a; 
    } 

    var _i; 

    for(_i=0; _i <= 100; ++_i) { 
     oldway() 
    } 
}).call(this); 

이 결과 :

time coffee test.coffee 

real 0m5.647s 
user 0m0.016s 
sys  0m0.076s 

time node test.js 

real 0m5.479s 
user 0m0.000s 
sys  0m0.000s 

JS는 도대체 커피 스크립트가 빠르다 무엇

time node test2.js 

real 0m5.904s 
user 0m0.000s 
sys  0m0.000s 

그래서 당신은 자신을 요청할 수 있습니다

를 걸립니다 ... ??? 그런 다음 코드를보고 자신에게 묻습니다. 문제를 해결해 봅시다!

(function() { 
    function oldway() 
    { 
     var a = []; 
     for (var i = 0; i <= 1000000; i++) 
      a.push(i); 
     return a; 
    } 

    var _i; 

    for(_i=0; _i <= 100; ++_i) { 
     oldway() 
    } 
}).call(this); 

우리는 다음 JS 스크립트에 작은 수정을하고 a.push(i)-a[i] = i을 변경 한 다음 다시 시도 할 수 있습니다 ... 그리고이 작은 변화가보다 빠르게 만들었

time node test2.js 

real 0m5.330s 
user 0m0.000s 
sys  0m0.000s 

붐 것입니다 우리의

// Generated by CoffeeScript 1.6.2 
(function() { 
    var i, new_way; 

    for (i = 0; i <= 100; ++i) { 
    new_way = function() { 
     var _j, _results; 

     return (function() { 
     _results = []; 
     for (_j = 0; _j <= 1000000; _j++){ _results.push(_j); } 
     return _results; 
     }).apply(this); 
    }; 
    new_way(); 
    } 

}).call(this); 
: 커피 스크립트는 이제 이것에

... 생성 된 커피 스크립트를 보면 ... 그 두 변수를 제거 할 수 있습니다

및 붐

time node test.js 

real 0m5.373s 
user 0m0.000s 
sys  0m0.000s 

그럼 내가 무엇을 말하려고하고있어 높은 언어를 사용하는 큰 혜택이 있다는 것입니다. 생성 된 CoffeeScript는 최적화되지 않았습니다. 하지만 순수한 js 코드에서 그렇게 멀지 않았습니다. clockworkgeek이 밀어 넣기 대신 색인을 사용하여 실제로 사용하려고 시도한 코드 최적화는 실제로 생성 된 coffeescript보다 느리게 작동하고 역효과를내는 것처럼 보였습니다.

그런 종류의 최적화는 찾기 어렵습니다. 다른면에서, 버전에서 버전까지, coffeescript는 현재 브라우저 또는 인터프리터에 최적화 된 js 코드를 생성 할 수 있습니다. CoffeeScript는 변경되지 않은 채로 남아 있지만 속도를 높이기 위해 다시 생성 될 수 있습니다.

자바 스크립트로 직접 작성하는 경우 실제 컴파일러 에서처럼 코드를 실제로 최적화하는 방법이 있습니다.

다른 흥미로운 부분은 언젠가 CoffeeScript 나 자바 스크립트의 다른 생성기가 (jslint와 같은) 코드를 분석하고 일부 변수가 필요하지 않은 코드 부분을 제거하는 데 사용될 수 있다는 것입니다. 다른 기능을 다르게 컴파일합니다. 변수가 필요하지 않을 때 속도를 높이는 인수. purej를 사용한다면 JIT 컴파일러가 있어야하고, coffeescript에도 도움이 될 것입니다.

예를 들어 나는 for 루프 내부에서 new_way = (function...을 제거하여 마지막으로 커피 스크립트를 최적화 할 수 있습니다. 한 스마트 프로그래머는 여기에서 일어나는 유일한 일은 변수를 변경시키지 않는 각 루프의 기능을 재사용한다는 것입니다. 이 함수는 함수 범위에서 만들어지며 각 루프에서 다시 작성되지 않습니다. 즉 그래서이 꽤 많이 있습니다 ...

time node test.js 

real 0m5.363s 
user 0m0.015s 
sys  0m0.000s 

가 많이 변경되지해야한다고 말했다.

+0

마지막 블록을 생성 한 CoffeeScript 코드에 어떤 변화를 주었습니까? – pilau

+0

'_i'을 삭제했습니다. coffescript 코드는 변경하지 않았습니다. 나는 생성 된 코드를 편집했다. –

+0

괜찮습니다. 처음에는 CoffeeScript로 더 나은 코드를 출력하기위한 실용적인 솔루션을 제시한다고 생각했습니다. CoffeeScript 변환기가 기술적으로 항상 향상되어 더 많은 최적화 된 코드를 생성 할 수있는 레이어라는 점을 확인하기 위해 변경 한 것을 보았습니다. – pilau

1

난 당신이 하나 개의 브라우저의 시간을 인쇄하는 것이 ...

것 같다, 루이 포레 - 라크의 대답에 뭔가를 추가 할. 그리고 BTW "x.push (I)"하지 빠르다 "X [I] = 1"에 따른 jsperf : https://jsperf.com/array-direct-assignment-vs-push/130

Chrome: push => 79,491 ops/s; direct assignment => 3,815,588 ops/s; 
IE Edge: push => 358,036 ops/s; direct assignment => 7,047,523 ops/s; 
Firefox: push => 67,123 ops/s; direct assignment => 206,444 ops/s; 

다른 포인트 - (> x.call (본)과 x.apply 이것을) ... 나는 그 어떤 성과 이유도 알지 못한다. 그하여도 jsperf 확인한다 : 언급 http://jsperf.com/call-apply-segu/18

Chrome: 
direct call => 47,579,486 ops/s; x.call => 45,239,029 ops/s; x.apply => 15,036,387 ops/s; 
IE Edge: 
direct call => 113,210,261 ops/s; x.call => 17,771,762 ops/s; x.apply => 6,550,769 ops/s; 
Firefox: 
direct call => 780,255,612 ops/s; x.call => 76,210,019 ops/s; x.apply => 2,559,295 ops/s; 

첫째 - 내가 실제 브라우저를 사용했다.

두 번째로 - for 루프로 테스트를 연장했습니다. 하나의 호출로 테스트가 짧아지기 때문에 ...

마지막으로 적어도이 없습니다 - 이제 모든 브라우저의 테스트처럼 다음 여기에 내가 커피 스크립트 1.10.0이

console.time('coffee');// added manually 
(function() { 
    var new_way; 

    new_way = function() { 
    var i, results; 
    return (function() { 
     results = []; 
     for (i = 0; i <= 1000000; i++){ results.push(i); } 
     return results; 
    }).apply(this); 
    }; 

    // manually added on both 
    var i; 
    for(i = 0; i != 10; i++) 
    { 
    new_way(); 
    } 

}).call(this); 
console.timeEnd('coffee');// added manually 
(그의 대답에 주어진 동일한 코드로 컴파일)를 사용


이제 자바 스크립트

console.time('js'); 
(function() { 

    function old_way() 
    { 
    var i = 0, results = []; 
    return (function() 
    { 
     for (i = 0; i <= 1000000; i++) 
     { 
     results[i] = i; 
     } 
     return results; 
    })();// replaced apply 
    } 

    var i; 
    for(i = 0; i != 10; i++) 
    { 
    old_way(); 
    } 

})();// replaced call 
console.timeEnd('js'); 

for 루프의 한계 값이 낮이든 높이 때문에 그것은 항상 커피는이 테스트에서 가장 느린 것을,

여기

Chrome: coffee: 305.000ms; js: 258.000ms; 
IE Edge: coffee: 5.944,281ms; js: 3.517,72ms; 
Firefox: coffee: 174.23ms; js: 159.55ms; 

내가 언급이 있어야 결과 ... 꽤 느린 테스트 (10 * 1000000 전화)이 될 것입니다. 파이어 폭스에서 이러한 코드를 테스트하여 볼 수 있습니다.

내 최종 답변 : - 나는 커피 스크립트 정말 익숙하지 않은,하지만 난 아톰 편집기를 사용하고 있기 때문에, 그것으로 고개가 내 첫 번째 패키지를 빌드하려고 싶었지만, DRIVED

먼저 말을 자바 스크립트로 돌아 가기 ... 잘못된 것이 있으면 나를 바로 잡을 수 있습니다.

coffeescript를 사용하면 코드를 적게 쓸 수 있지만 최적화와 관련하여 코드가 무거워집니다. 내 자신의 의견 ->이 "Coffeescripting"언어에서 "생산력"이라고 볼 수는 없습니다 ...

성능으로 돌아가려면 : 가장 많이 사용되는 브라우저는 Chrome 브라우저입니다 (src : w3schools.com/ 브라우저/browsers_stats.asp)와 60 %의 테스트 결과를 통해 수동으로 입력 된 자바 스크립트가 Coffeescript보다 약간 빠르다는 것을 알 수있었습니다 (IE 제외 ... - 훨씬 빠름). 소규모 프로젝트를 위해 Coffeescript를 권하고 싶지만, 아무도 마음에 들지 않으면 원하는 언어를 유지하십시오.

관련 문제