打字省略号是性能问题吗
Is a typescript ellipsis a performance concern?
Typescript省略号生成JavaScript,该JavaScript在函数开头用arguments
构造一个数组。
function blah(...args: any[]){
}
变为:
function blah() {
var args = [];
for (var _i = 0; _i < (arguments.length - 0); _i++) {
args[_i] = arguments[_i + 0];
}
}
在考虑性能的情况下查看我的项目时,我想知道这种构造是否是经常被称为代码的性能问题?
是吗?
回答这个问题的最简单方法是运行一些测试。JsPerf是一个非常棒的工具。我自己也很好奇,所以我在这里设置了一个测试,是的,这可能是一个重大的性能打击。多少取决于您调用该函数的频率、它所做的工作量以及参数列表可能需要多长时间。
所有这些都表明,我非常相信80/20规则,尤其是在优化方面。大多数时候,这并不重要,所以如果它让代码更漂亮,就继续使用它。
我同意Jeffrey的回答,但我认为遗漏了一点。
您会问rest参数是否会导致性能下降,但与之相比呢?
例如,如果我有以下功能:
var addNums = function(...nums: number[]) {
var result = 0;
for (var i = 0; i < nums.length; i++) {
result += nums[i];
}
return result;
};
我可以使用哪些替代方案?
如果我想避免使用rest参数,我可能会接受一个数组参数,因为我们不知道可能有多少nums。在这两种情况下,运行时性能会相似。因此,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中尝试,但您需要为所有重载提供一个兼容的方法体,然后检查不太可能更快的参数(尽管您可以测量它)。
因此,除非你要调用这个方法一千次,否则它不太可能比其他方法更糟糕。
我也很好奇,因为我的日志函数使用了它们,并且被调用了很多。
我测试了
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()
- 使用正则表达式评估电子邮件地址时出现性能问题
- 在循环中附加事件处理程序时出现浏览器性能问题
- 角度指令性能问题
- 奇怪的Kineticjs性能问题
- 使用HTML和JS的iPhone游戏中的性能问题,以及appMobi
- 菜单性能问题
- 性能问题:通用选择器与单独绑定
- 离子框架移动应用程序性能问题
- 性能问题高图表图和 socket.io
- 样式 DOM 上的 $.before() 性能问题
- Ajax发布到PHP脚本,每5秒查询一次MySQL数据库的性能/问题
- 循环的 JavaScript 性能问题
- 性能问题:存储对DOM元素的引用与使用选择器相比
- 很多主干视图-性能问题
- jquery性能问题,操作注册
- 在web工作者、快速定时器和$scope中遇到AngularJS性能问题$apply()
- 使用pixi和p5声音库制作的听觉反应视觉效果的性能问题
- 更多的 DOM 元素会产生性能问题
- 主要面临性能问题
- 使用ng-grid的问题-性能,响应