min*_*tea 10 javascript math performance callstack function
所以,我正在编写一个2d Javascript物理模拟.性能很好,但我正在进行优化以使其更好.所以,因为程序适用于很多物理几何,我在程序中进行了几个毕达哥拉斯定理计算.总之,大约有五个计算; 它们一起运行大约每秒一百万次.所以,如果我将这个简单的毕达哥拉斯定理代码放入一个新函数并调用它,我认为它会提高性能; 毕竟,浏览器的编译方式较少.所以,我在Firefox中运行代码,得到了...... 计算执行时间增加了400%.
怎么样?它是相同的代码:Math.sqrt(x*x + y*y),那么如何将它作为一个函数加减速呢?我假设原因是函数需要时间才能被调用,而不执行代码,并且每秒增加一百万个这样的延迟会减慢它的速度?
这对我来说似乎相当惊人.这也适用于预定义的js函数吗?这似乎不太可能,如果是这样,他们如何避免呢?
代码过去是这样的:
function x()
{
dx=nx-mx;
dy=ny-my;
d=Math.sqrt(dx*dx+dy*dy);
doStuff(...
}
Run Code Online (Sandbox Code Playgroud)
我试过的是这个:
function x()
{
dx=nx-mx;
dy=ny-my;
d=hypo(dx,dy);
doStuff(...
}
function hypo(x,y)
{
return Math.sqrt(x*x+y*y);
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
JS从未有过的预编译语言中的函数调用可以忽略甚至优化.除此之外,很大程度上取决于浏览器.
它们是解释性语言中所有表现的死亡,JS直到最近才出现.大多数现代浏览器都有JIT(Just In Time)编译器,这是过去JS解释器的一个巨大升级,但我相信对另一个作用域的函数调用仍然需要一些开销,因为JS的调用对象必须确定实际调用的是什么,这意味着什么在各种范围链上行进.
因此,作为一般规则:如果您关心IE8和较低版本的Chrome和Firefox,请避免功能调用期.特别是内循环.对于JIT浏览器,我希望在其他函数中定义的函数通常是有益的(但我仍然会测试,因为这是IE9的全新技术,对其他人来说相对较新).
另一件要警惕的事情.如果函数特别复杂,JIT可能无法对其进行优化.
https://groups.google.com/forum/#!msg/closure-compiler-discuss/4B4IcUJ4SUA/OqYWpSklTE4J
但要理解的重要一点是,当某些东西被锁定并且只在一个上下文中调用时,就像函数中的函数一样,JIT应该很容易进行优化.在函数外部定义,它必须确定正确调用该函数的哪个定义.它可能是一个外部功能.它可能是全球性的.它可能是window对象的构造函数原型的属性等等......在函数是第一类的语言中,意味着它们的引用可以像传递数据一样传递给args,你无法真正避免这一步在你当前的背景之外.
因此,尝试在X中定义hypo来看看会发生什么.
来自解释时代的另外几个一般提示可能在JIT中仍然有价值:
'.' 运算符someObject.property
,是一个值得缓存的过程.由于每次使用时都有相关的调用对象查找过程,因此成本开销很大.我想Chrome不会保留此过程的结果,因为对父对象或原型的更改可能会改变它在给定上下文之外实际引用的内容.在你的例子中,如果一个循环正在使用x(如果x在与JIT中的循环相同的函数中定义 - 解释器中的谋杀可能是好的甚至是有用的),我会尝试在使用它之前将Math.sqrt赋值给var在低.对当前函数的上下文之外的东西有太多的引用可能会导致一些JIT决定优化它不值得,但这是我的纯粹推测.
以下可能是循环数组的最快方法:
Run Code Online (Sandbox Code Playgroud)//assume a giant array called someArray var i = someArray.length; //note the property lookup process being cached here //'someArray.reverse()' if original order isimportant while(i--){ //now do stuff with someArray[i]; }
注意:由于某种原因,代码块在这里不起作用.
这样做可能会有所帮助,因为它基本上将加/减步骤和逻辑比较变为仅减量,完全消除了对左/右比较运算符的需要.请注意,在JS中,右侧递减运算符意味着我被传递以进行求值,然后在块内部使用之前递减.while(0)
评估为假.