Javascript功能优化(`)`
阅读文档时,我发现了一个简单的优化,大大提高了JavaScript的性能。Javascript功能优化(`)`
原始代码:
function parseRow(columns, parser) {
var row = {};
for (var i = 0; i < columns.length; i++) {
row[columns[i].name] = parser.readColumnValue();
}
}
优化代码:
var code = 'return {\n';
columns.forEach(function(column) {
code += '"' + column.name + '":' + 'parser.readColumnValue(),\n';
});
code += '};\n';
var parseRow = new Function('columns', 'parser', code);
这里找到:https://github.com/felixge/faster-than-c
为什么它运行快20%?
我相信它会删除for
语句,但不会有forEach
具有相同的计算成本?
不同之处在于您只使用forEach
至构造的优化函数。创建函数后,内部没有任何循环:loop is unrolled和列名称为hardcoded。然后将该方法编辑为一个工作函数,该函数甚至可以编译为机器代码depending on the engine。这将导致两个性能方面的改进:
- 通过消除
for
循环条件检查(i < columns.length
)完全,没有分支,并 - 通过硬编码的
column[i].name
值转换成多个语句,你删除评估column[i]
和查找到column.name
在每一步。
所以调用new Function(...)
与作为String
通过代码后,您parseRow
变量得到参照以下功能:
function parseRow(columns, parser) {
return {
"columnOne": parser.readColumnValue(),
"columnTwo": parser.readColumnValue(),
"columnThree": parser.readColumnValue(),
...
};
}
注意,没有任何的循环,分支,或其他查询在该代码中,除了多个parser.readColumnValue()
调用。
这为什么在JavaScript中可能?
在JavaScript中如此高效地工作的原因是因为任何网页中的JavaScript源代码无论如何都需要由JS引擎解释或编译。你不会发布你的网页编译的可执行文件,甚至(有些)预编译的字节码(如Java或.NET)。每载入一个新的.js
文件,浏览器在运行之前都会从头开始编译它(呃,确切地说,在现代引擎中,它是解释和编译之间的东西,即JITting)。
这意味着在运行时从字符串(即编译代码)创建工作函数的效率并不比从手写代码读取.js文件低。与C/C++程序比较,该程序编译为机器码(即可执行文件尽可能靠近CPU)before it reaches the customer(在所有合理的情况下)。
如果你想在C++(一种self-modifying code)中做到这一点,你将不得不捆绑一个编译器沿着你的应用程序来构建代码,并且构建这个函数的代价会超过你获得的好处你最终会开始它。例如,在.NET中,对于程序emit methods or even assemblies at run time而言,这并不罕见,然后它将JIT编译为机器代码,以允许潜在的性能改进,例如您的问题。
性能提升取决于JavaScript引擎以及正在处理的数据。我们不知道“快20%”的确切情况(除了使用node.js)。在某些情况下它可能会变慢。 (编辑:您需要经常调用该功能足以超过建设成本)。增益的一些可能原因:
优化后的代码会创建一个对象字面值。以前的版本不断地将值分配给不存在的属性。这有一些相关的成本。
row[columns[i].name]
有三个查找,而优化版本没有,一旦函数被构造。不要忘记,row[columns[i].name]
尚不存在,所以查找更昂贵。 columns.length
也是查找。
它是否在谈论20%的功能创建逻辑本身?或者每次调用函数parseRow?如果是后一种情况,我会假设增益发生是因为优化代码中没有for循环。 (在第一种情况下,for循环会在每次调用parseRow函数时运行,并且多次调用columns.length属性也可能归因于原始代码的缓慢性,只是我的2美分:)) – 2014-09-13 13:10:51
相关(对于V8)http ://www.youtube.com/watch?v = UJPdhx5zTaw – 2014-09-13 13:21:30
当'columns'的大小足够大时,'优化后的代码'似乎没有更快。请参阅[jsPerf](http://jsperf.com/javascript-optimization-with-new-function) – rhgb 2014-09-13 14:02:48