我写了a basic Game of Life demo来了解一些ES6 / typedArray功能。使用600×600字段(在我的Macbook Air上)我在Firefox Nightly中获得每秒约57帧(根据about:config> layers.acceleration.draw-fps),这是完全可以接受的。但是在Chrome中,我的平均值为3.5fps(使用开发工具帧速率计数器测量)。
通过一些调试(参见repo中的提交)我将慢速代码缩小到为每个单元构建多个活动邻居的部分。在Firefox中计算整个字段大约需要18-19ms(与性能接近60fps一致)但在Chrome中需要175-185ms。注释掉下面的代码显然会破坏演示,但是会平衡其余代码的性能(即不是画布渲染,这是缓慢的部分)。
liveNeighbours = liveNeighbours + field[index - width - 1]
+ field[index - width]
+ field[index - width + 1]
+ field[index - 1]
+ field[index + 1]
+ field[index + width - 1]
+ field[index + width]
+ field[index + width + 1];
这样您就可以看到我将代码放入CodePen的问题:http://codepen.io/anon/pen/aNdzPP
任何人都可以指出我做错了什么,或者Chrome在这个JS上只是病态缓慢?如果是这样我会提交一个错误,但我想确保我没有做一些愚蠢的事情。
答案 0 :(得分:3)
问题是越界访问。例如。对于index == 0,您正在访问字段[-width-1],字段[-width]等。 V8没有针对越界访问进行优化,因为它们通常都是错误的。这也是这种情况:读出界限返回'undefined',当添加到其他数字时强制转换为NaN,因此对于字段边缘的任何字段,liveNeighbours总是NaN,因此没有任何比较会返回true,因此fieldBuffer将始终在该索引处保持为零。 解决问题的一种简单方法是将数组访问包装到辅助函数中:
function get(array, index) {
if (index < 0 || index >= array.length) return 0;
return array[index];
}
liveNeighbours = get(field, index - width - 1) + get(field, index - width) + ...