Javascript:对象复制、全局变量和性能

标签 javascript performance global-variables local-variables

我有一个非常复杂的问题要问:)

我目前正在开发一款 html5 canvas 游戏。特定于游戏 map 的变量位于单独的文件中(我们称之为 game.js),与游戏引擎分开(我们称之为 engine.js)。

我读到全局变量在 JS 中的使用比局部变量慢。因此,在 game.js 中,我创建了一个包含所有游戏特定变量的全局变量。在 engine.js 中,我将这个全局对象复制到局部变量,在那里我删除了这个全局对象。

这是有效的。但我知道分配对象只会传递对这些对象的引用。

因此我的问题是:当我在初始化结束时删除全局对象时,它的性能是否就像我在 engine.js 中直接将所有变量声明为局部变量一样,还是会更慢,好像我在 engine.js 中的局部变量只是对全局对象的引用?

我可以在 engine.js 中将所有变量声明为本地变量,但如果以后我想制作其他 map /游戏,那么将特定于 map 的内容分开对我来说会很有用。

例如:

游戏.js:

Game = function() {
this.x = 16;
this.y = 16;
this.myObject = {"test": "hello", "action": "none"};
}
game = new Game();

引擎.js: //...

var x = game.x;
var y = game.y;
var obj = {"test": game.myObject.test, "action": game.myObject.action};

//...

在这个例子中,x、y 和 obj 的性能会和局部变量一样快,还是更慢?

注意:我并没有真正检查全局变量和局部变量的性能差异,但我认为我读到的是正确的。

希望我的问题足够清楚而不是愚蠢 :) 如果您有任何想法...谢谢!

最佳答案

在现代浏览器中,局部变量和全局变量之间可能没有太大的性能差异。

但是存在内存消耗问题 - 只要页面保持打开状态,全局变量就会持续存在,而局部变量是 garbage collected在控制离开他们的范围之后。使用局部变量可以减少出现 memory leak 的几率.

更新

评论线程中的长篇大论促使我编写了一个测试脚本来测量对比全局和局部范围访问的执行速度差异。

最初似乎没有区别,结果也各不相同,没有特别偏向于其中之一。然而,@DaveNewton 提供了一个反例,它始终显示局部变量的性能提高了一个数量级。


火狐 7

Milliseconds used for 20000 global accesses: 132

Milliseconds used for 20000 local accesses: 159

Internet Explorer 9

Milliseconds used for 20000 global accesses: 1750

Milliseconds used for 20000 local accesses: 1699

谷歌浏览器 14

Milliseconds used for 20000 global accesses: 46

Milliseconds used for 20000 local accesses: 55

测试脚本本身

<html>
<head>
<script type="text/javascript">

function t() {

var test = function () {}
test.issue = new String("hello");

var start = new Date().getTime();
(function() {
    (function() {
        (function() {
            (function() {
                (function() {
                    (function() {
                        (function() {
                            var a = document.getElementById("a");
                            for (var i = 0; i < 20000; i++) {
                                a.innerHTML = test.issue.toString();
                            }
                            a = null;
                        })();
                    })();
                })();
            })();
        })();
    })();
})();
var stop = new Date().getTime();
document.getElementById("a").innerHTML = "Milliseconds used for 20000 global accesses: " + (stop - start);


var start = new Date().getTime();
(function() {
    (function() {
        (function() {
            (function() {
                (function() {
                    (function() {
                        (function() {
                            var c = document.getElementById("c");
                            var testx = {};
                            testx.issue = new String("hello");
                            for (var i = 0; i < 20000; i++) {
                                c.innerHTML = testx.issue.toString();
                            }
                            c = null;
                        })();
                    })();
                })();
            })();
        })();
    })();
})();
var stop = new Date().getTime();
document.getElementById("c").innerHTML = "Milliseconds used for 20000 local accesses: " + (stop - start);

}

window.onload = function () {
    document.getElementById('b').onclick = t;
}

</script>
</head>
<body>
<div align="center"><button id="b">Run Test</button></div>
<div id="a"></div>
<div id="c"></div>
</body>

</html>

一个反例,展示了对局部变量的更快访问。

var t0 = new Date();
var i; 
for (i=0; i<10000000; i++); 
var t1 = new Date(); 
function count() { for (var i=0; i<10000000; i++); } 
var t2 = new Date(); 
count(); 
var t3 = new Date(); 
d = document; 
d.write('Without local variables = ', t1-t0, '<br />'); 
d.write('With local variables = ', t3-t2, '<br />');

关于Javascript:对象复制、全局变量和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7650209/

相关文章:

ruby-on-rails - 在 Ruby 中初始化具有高索引的空数组是否昂贵?

java - IBM 堆分析器 - 最终确定方法

c# - ASP.NET MVC 全局变量

Javascript 在其他函数中重用变量

c# - 使用 linq 更新对象的性能更好

c++ - 如何在 C++ 的 MFC 窗体中访问全局变量

javascript - 添加 javascript 后标题元素不会显示,但删除它后会显示

javascript - 无法在 Angular 中为超链接创建自定义单击指令

javascript - 停止多次播放动画

javascript - "System.out.println"在 JS 中如何工作?... :)