Javascript profiling mystery - 闭包变量

时间:2016-02-02 23:53:09

标签: javascript profiling google-chrome-devtools profiler ecmascript-5

如果在闭包内定义变量的话,我正在测试性能(使用chrome时间轴)。因此,它的值不会暴露给用户。

正如预期的那样run_proto_fn运行速度快几倍,垃圾收集最少,内存堆也很少。

但是run_proto_obj碰巧恰好相反,好像在对象原型属性属性中使用非函数值代价很高。

有人可以在这里分享一些清晰度吗?



SOME = function(){};
SOME.prototype.exe = function(v){
	var x = {
		a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
		b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
		c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
	};
	return x[v];
};

SOME2 = function(){};
SOME2.prototype.exe = function(v){
	return this.exes[v];
};
SOME2.prototype.exes = {
	a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
	b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
	c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
};
SOME_FN = function(){};
SOME_FN.prototype.exe = function(v){
	var x = {
		a: function(p){this.p1 = p;return this;},
        b:function(p){this.p2 = p*3;return this;},
        c:function(p){this.p3 = p*99;return this;},
    };
  return x[v].call(this,42);
};

SOME_FN2 = function(){};
SOME_FN2.prototype.exe = function(v){
    return this.exes[v].call(this,42);	
};
SOME_FN2.prototype.exes = {
    a: function(p){this.p1 = p;return this;},
    b:function(p){this.p2 = p*3;return this;},
    c:function(p){this.p3 = p*99;return this;},
};

var a1 = a2 = a_fn1 = a_fn2 = [];
	

var run_local_obj = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x1 = new SOME();
		x1.exe('a');
		a1.push(x1);
	}
};
var run_proto_obj = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x2 = new SOME2();
		x2.exe('a');
		a2.push(x2);
	}
};
var run_local_fn = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x1 = new SOME_FN();
		x1.exe('a');
		x1.exe('b');
		x1.exe('c');
		a_fn1.push(x1);
	}
};
var run_proto_fn = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x2 = new SOME_FN2();
		x2.exe('a');
		x2.exe('b');
		x2.exe('c');
		a_fn2.push(x2);
	}
};

<button onclick="run_local_obj(this)">local obj</button>
<button onclick="run_proto_obj(this)">proto obj</button>
<button onclick="run_local_fn(this)">local obj FN</button>
<button onclick="run_proto_fn(this)">proto obj</button>
&#13;
&#13;
&#13;

我听过一句话:

  每次函数运行时都会定义

闭包变量

但是,我仍然有雾。

1 个答案:

答案 0 :(得分:12)

我尝试运行测量,首先我注意到只是使用你问题中的代码很难理解发生了什么。

如果我逐个运行这些测试(单击按钮并查看时间轴),那么对于每次下一次运行,结果都会有很大不同。 从几次运行开始看起来第三次(run_local_fn)通常比其他运行时间长。

然后我尝试以向后的顺序运行它们(单击4到1的按钮)并得到完全不同的结果 - run_local_obj是最长的。

所以我稍微修改了测试代码,以便能够获得稳定的结果。

完整代码is here,您可以克隆存储库并在本地测试它。

以下是我在Chrome中运行每个测试的方式(我使用python -m SimpleHTTPServer 8082文件夹中的js-perf-test启动了它:

  • 使用http://localhost:8082/perf.html打开标签,打开开发工具
  • 开始时间线录制
  • 点击按钮
  • 在控制台中等待结果(最小/最大/平均值)
  • 停止时间线录制

结果稳定且可重复(时间和时间线视图),这是一个测试:

那么我们在这里看到的是:

1)run_proto_obj最快,run_local_obj接近它。

我认为run_proto_obj最有效率,因为它使用静态定义的对象和字符串。 并且JS引擎可能能够优化run_local_obj,因此x对象被重用,而不是每次都创建。

2)run_local_fn是最慢的。

此处我们有本地x对象和动态字符串计算,比其他测试更多floating部分。

3)run_proto_fnrun_local_fn快,但比前两个函数慢。

我认为这也是预期的,a, b, c的对象只定义一次(因此它比run_local_fn快。)

与前两个函数相比,它会动态计算结果字符串,因此速度较慢。

回到你的问题:

  

正如预期的那样,run_proto_fn运行速度提高了几倍,垃圾收集最少,内存堆也很少。   但是run_proto_obj恰好相反,就好像在对象原型属性属性中具有非函数值一样昂贵。

它让我觉得你没有正确设置实验。 根据上面的结果,run_proto_obj实际上是最快的。

更新:我刚在Firefox中尝试了相同的测试,结果类似:

  • `run_local_obj' - 344.85ms
  • `run_proto_obj' - 151.47ms
  • `run_local_fn' - 788.08ms
  • `run_proto_fn' - 265.21ms

run_proto_obj最快,run_local_fn最慢。