den*_*isL 5 javascript performance closures interpreter functional-programming
最近我读过这个性能指南让我们更快地使网络变得困惑并且被"避免关闭陷阱"建议所迷惑(好像这些建议是针对变量范围是动态的CommonLisp用户提供的):
Run Code Online (Sandbox Code Playgroud)var a = 'a'; function createFunctionWithClosure() { var b = 'b'; return function () { var c = 'c'; a; b; c; }; } var f = createFunctionWithClosure(); f();
f调用when时,引用a比引用慢b,这比引用慢c.
很明显,引用局部变量c比b快,但是如果iterpreter写得正确(没有动态范围 - 类似于链式散列表查找......),速度差异应该只是边际.或不?
你说得对。现代 JS 引擎会对 之scope chain lookup类的进行prototype chain lookup很多优化。意思是,据我所知,引擎试图保存某种带有访问节点的哈希表。
仅当没有eval()(显式或隐式,例如setTimeout)或try-catch子句或a with statement调用时,这才有效。由于这样的构造,解释器无法确定如何访问数据,并且需要“回退”到经典模式,scope chain lookup这实际上意味着,它必须爬行所有父上下文variable / activation objects并尝试解析搜索到的变量名称。当然,对于距离查找处理开始位置“很远”的对象/名称,此过程将花费更多时间。这反过来意味着,访问数据global object总是最慢的。
在您的代码片段中,查找过程a如下
anonymous function -> Execution Context -> Activation Object (not found)
anonymous function -> Execution Context -> [[ Scope ]]
- createFunctionWithClosure
- global scope
createFunctionWithClosure -> Activation Object (not found)
global scope -> Variable Object (found)
Run Code Online (Sandbox Code Playgroud)
所描述的查找过程适用于 ECMAscript Edition 262 第三版。ECMAscript 第 5 版有一些根本性的变化。
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |