coffeescript比javascript更快?

lhk*_*lhk 9 javascript performance benchmarking html5 coffeescript

Javascript无处不在,在我看来,它一直在变得越来越重要.大多数程序员都同意,虽然Javascript本身很难看,但它的"领域"确实令人印象深刻.凭借HTML5的功能和现代浏览器的速度,通过Javascript部署应用程序是一个有趣的选择:它可能是你可以获得的跨平台.

自然的结果是交叉编译器.主要可能是GWT,但还有其他几种选择.我最喜欢的是Coffeescript,因为它只在Javascript上添加了一个薄层,并且比例如GWT更"轻量级".

只有一件事一直困扰着我:虽然我的项目相当小,但性能始终是一个重要的话题.这是一个引用

GWT SDK提供了一组核心Java API和小部件.这些允许您用Java编写AJAX应用程序,然后将源代码编译为高度优化的JavaScript

Coffeescript也被优化了吗?由于Coffeescript似乎大量使用非常见的Javascript功能,我担心他们的性能如何比较.

您是否有过与Coffeescript相关的速度问题的经历?你知道一个很好的基准比较吗?

clo*_*eek 38

抱怨复活一个古老的话题,但它也让我很担心.我决定执行一个小测试,我知道的一个最简单的性能测试是将连续值写入数组,随着数组的增长,内存以熟悉的方式消耗,并且'for'循环在现实生活中足够常见,需要考虑相关.

经过几次红色鲱鱼后,我发现coffeescript最简单的方法是:

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

这使用闭包并返回数组作为结果.我的相当于:

function oldway()
{
    var a = [];
    for (var i = 0; i <= 1000000; i++)
        a[i] = i;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,结果是相同的,它也以类似的方式生成数组.接下来,我用chrome分析了每次100次的平均值.

newway() | 78.5ms
oldway() | 49.9ms
Run Code Online (Sandbox Code Playgroud)

Coffeescript慢了78%.我反驳说"你写的CoffeeScript最终运行的速度和你写的JS一样快(并且通常比它快)"(Jeremy Ashkenas)


附录:我还怀疑人们普遍认为"JS中始终存在一对一的等同物".我尝试用这个重新创建自己的代码:

badway = ->
    a = []
    for i in [1..1000000]
        a[i] = i
    return a
Run Code Online (Sandbox Code Playgroud)

尽管有相似之处,它仍然被证明慢了7%,因为它增加了对方向(增量或减量)的额外检查,这意味着它不是直接平移.

  • 为什么要为一个有趣的答案道歉.我不会期望差异很大.当然可以争辩说,将一个从0到1000000的所有数字添加到一个数组并不是一个正常的用例,你只是看了一个浏览器.但78%!?那是艰难的+1 (5认同)

Loï*_*oix 23

这一切都非常有趣,并且有一个道理,咖啡脚本不能比完全优化的javascript更快地工作.

也就是说,因为咖啡脚本正在生成javascript.有办法让它值得.可悲的是,情况似乎并非如此.

让我们举个例子:

new_way = -> [0..1000000]
new_way()
Run Code Online (Sandbox Code Playgroud)

它用咖啡脚本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);
Run Code Online (Sandbox Code Playgroud)

而clockworkgeek提供的代码是

function oldway()
{
    var a = [];
    for (var i = 0; i <= 1000000; i++)
        a[i] = i;
    return a;
}
oldway()
Run Code Online (Sandbox Code Playgroud)

但由于咖啡脚本隐藏了一个范围内的函数,我们也应该为javascript做这个.我们不想对窗口进行检查吗?

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

所以这里我们有代码实际上做同样的事情.然后我们想实际测试两个版本.

咖啡脚本

for i in [0..100]
    new_way = -> [0..1000000]
    new_way()
Run Code Online (Sandbox Code Playgroud)

生成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);
Run Code Online (Sandbox Code Playgroud)

所以现在我们要更新我们的Javascript.

(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);
Run Code Online (Sandbox Code Playgroud)

结果如下:

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
Run Code Online (Sandbox Code Playgroud)

js需要

time node test2.js

real    0m5.904s
user    0m0.000s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

所以你可能会问自己......什么地狱咖啡脚本更快?然后你看看代码并问自己......所以让我们试着解决这个问题!

(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);
Run Code Online (Sandbox Code Playgroud)

然后我们将对JS脚本做一个小修复,然后更改a[i] = ia.push(i)然后让我们再试一次......然后再使用BOOM

time node test2.js

real    0m5.330s
user    0m0.000s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

这个小改动使它比我们的CoffeeScript Now更快,让我们看一下生成的CoffeeScript ...并删除那些双变量......

对此:

// 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);
Run Code Online (Sandbox Code Playgroud)

和BOOM

time node test.js

real    0m5.373s
user    0m0.000s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

那么我想说的是使用更高级的语言有很大的好处.生成的CoffeeScript未进行优化.但与纯粹的js代码相差不远.clockworkgeek试图直接使用索引而不是推送使用的代码优化实际上似乎适得其反,并且比生成的coffeescript工作得慢.

事实上,这种优化很难找到并修复.另一方面,从版本到版本,coffeescript可以为当前的浏览器或解释器生成优化的js代码.CoffeeScript将保持不变,但可以再次生成以加快速度.

如果你直接用javascript编写,现在有办法真正优化代码,就像使用真正的编译器一样.

另一个有趣的部分是,有一天,CoffeeScript或javascript的其他生成器可用于分析代码(如jslint)并删除不需要某些变量的代码部分...使用不同的参数编译函数以加快速度不需要某些变量的事情.如果你有purejs,你将不得不期望有一个JIT编译器能够正确地完成工作并且它对coffeescript也有好处.

例如,我可以最后一次优化咖啡脚本..通过new_way = (function...从for循环中删除 .一个聪明的程序员会知道,这里唯一发生的事情是对每个循环的函数的影响不会改变变量.该函数在函数范围内创建,不会在每个循环中重新创建.那说不应该改变太多......

time node test.js

real    0m5.363s
user    0m0.015s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

所以这就是它.


c69*_*c69 11

简答:.

CoffeeScript生成javascript,因此其最大可能速度等于javascript的速度.但是虽然你可以在低级别优化js代码(是的,听起来很讽刺)并获得一些性能提升 - 使用CoffeeScript你不能这样做.

但是在选择CS over JS时,代码的速度不应该是您的关注,因为大多数任务的差异可以忽略不计.


Daf*_*aff 8

Coffescript直接编译为JavaScript,这意味着在JS中对于任何Coffeescript源始终存在一对一的等价物.关于它没有什么不相同之处.性能增益可以来自优化的事物,例如Coffescript将Array长度存储在for循环中的单独变量中而不是在每次迭代中请求它.但这也应该是JavaScript中的常见做法,它本身并不是由语言本身强制执行的.

  • @Raynos CoffeeScript和Javascript之间的区别在于,如果你在Coffeescript中写道,新版本的CoffeeScript实际上可以优化它生成javascript的方式.如果你直接用javascript写的话.然后你还是搞砸了.如果不重写代码,您可以使用更快的代码. (4认同)
  • 这也适用于JavaScript.Googles V8比其他许多JavaScript引擎都有巨大的性能提升,而且会越来越好.但您无需重写JavaScript即可使用Google Chrome. (2认同)