4

argumentsTypescript ellipsis 生成 JavaScript,它在函数的开头构造一个数组。

function blah(...args: any[]){
}

变成:

function blah() {
    var args = [];
    for (var _i = 0; _i < (arguments.length - 0); _i++) {
        args[_i] = arguments[_i + 0];
    }
}

在考虑性能的情况下查看我的项目,我想知道这种结构是否是通常称为代码的性能问题?

是吗?

4

3 回答 3

7

回答这个问题的最简单方法是运行一些测试。 JsPerf是一个非常棒的工具。我自己很好奇,所以我在这里设置了一个测试,是的,它可能会对性能产生重大影响。多少取决于您调用该函数的频率、它所做的工作量以及参数列表可能获得多长时间。

所有这一切都表明我非常相信80/20 规则,尤其是在优化方面。大多数时候它并不重要,所以如果它使代码更漂亮,请继续使用它。

于 2013-07-26T22:41:25.850 回答
1

我同意杰弗里的回答,但我认为错过了一点。

您问休息参数是否会导致性能下降,但与什么相比?

例如,如果我有以下功能:

var addNums = function(...nums: number[]) {
    var result = 0;
    for (var i = 0; i < nums.length; i++) {
        result += nums[i];
    }
    return result;
};

我可以使用哪些替代品?

如果我想避免使用其余参数,我可能会接受一个数组参数,因为我们不知道可能有多少个 num。在这两种情况下,运行时性能将相似。因此,rest 参数只是为了方便调用代码:

addNums(1,1,2,3);

而不是

addNums([1,1,2,3]);

如果 TypeScript 具有带有自己的函数体的方法重载,您可以使用 C# 框架类库中使用的相同技巧,即为一系列重载提供固定方法,并使用 rest 参数来处理更多数量的情况参数 - 例如,您将具有方法签名,例如:

addNums(a: number, b: number)
addNums(a: number, b: number, c: number)
addNums(...nums: number[])

因此,在您的常见情况下,将调用非循环版本,但在边缘情况下,将运行性能较低的版本。

可以在 TypeScript 中尝试此操作,但您需要为所有重载提供一个兼容的方法主体,然后检查不太可能更快的参数(尽管您可以测量它)。

因此,除非您要调用此方法一千次,否则它不太可能比替代方法更糟。

于 2013-07-27T19:18:47.767 回答
0

我也很好奇,因为我的日志函数使用它们并且被调用了很多。

我测试过

function toArray(obj, start)
{
  var arr=[];
  for (var i=start||0, j=0, len=obj.length; i<len; ++i)
      arr[j++]=obj[i];
  return arr;
}

function toArrayPush(obj, start)
{
  var arr=[];
  for (var i=start||0, len=obj.length; i<len; ++i)
      arr.push(obj[i]);
  return arr;
}

function testArgToArrayPush(level)
{
  var args=toArrayPush(arguments, 1);
}

function testArgToArray(level)
{
  var args=toArray(arguments, 1);
}

function testArgTypescript(level)
{
  var args = [];
  for (var _i = 0; _i < (arguments.length - 1); _i++)
      args[_i] = arguments[_i + 1];
}

function testArgSlice(level)
{
  var args=Array.prototype.slice.call(arguments, 1);
}

在 node.js v0.10.18 上使用优秀的 benchmarkjs.com:

testArgToArrayPush x 4,505,312 ops/sec ±0.55% (64 runs sampled)
testArgToArray x 2,961,857 ops/sec ±2.37% (93 runs sampled)
testArgTypescript x 3,879,242 ops/sec ±1.15% (96 runs sampled)
testArgSlice x 1,060,084 ops/sec ±0.52% (95 runs sampled)
Fastest is testArgToArrayPush

这意味着

  • Typescript 版本足以应付大多数情况
  • 如果你有热点,你可以考虑使用 toArrayPush()
  • 避免 Array.prototype.slice()
于 2013-09-19T09:03:16.037 回答