偶尔发现一个想不通的问题
发布于 9 年前 作者 CoderIvan 5641 次浏览 最后一次编辑是 8 年前 来自 问答
'use strict'

const POSSIBLE = '0123456789ABCDEF'

function test01() {
	let session_id = ''
	for (let i = 0; i < 8; i++) {
		session_id += POSSIBLE[(Math.floor(Math.random() * POSSIBLE.length))]
	}
}

function test02() {
	var session_id = ''
	for (var i = 0; i < 8; i++) {
		session_id += POSSIBLE[(Math.floor(Math.random() * POSSIBLE.length))]
	}
}


;[test01, test02].forEach((func) => {
	let count = 1000 * 1000
	let now = Date.now()
	for (let i = 0; i < count; i++) {
		func()
	}
	let use_time = Date.now() - now
	console.log('Count = %d, Use Time = %d ms, Cost = %d ms/t', count, use_time, (use_time / count))
})

结果: Count = 1000000, Use Time = 780 ms, Cost = 0.00078 ms/t Count = 1000000, Use Time = 250 ms, Cost = 0.00025 ms/t

14 回复

两个Function间的差别是一个用了var,一个用了let

详情查看ES6里面var和let作用域问题,let是为了防止内存溢出污染问题

我猜的是,let会额外包裹一次函数,用来保证块级作用域

我试了一下 块级作用域所增加的环境对象对性能影响不是很大, 影响大的+=作用于let声明的变量.(其它操作符没具体测试, 试了++, 影响不大) 试试下面的代码

'use strict'

const POSSIBLE = '0123456789ABCDEF'

function test01() {
  let session_id = ''
  for (let i = 0; i < 8; i++) {
    // session_id += POSSIBLE[(Math.floor(Math.random() * POSSIBLE.length))]
    session_id = session_id + POSSIBLE[(Math.floor(Math.random() * POSSIBLE.length))]
  }
}

function test02() {
  var session_id = ''
  for (var i = 0; i < 8; i++) {
    // session_id += POSSIBLE[(Math.floor(Math.random() * POSSIBLE.length))]
    session_id = session_id + POSSIBLE[(Math.floor(Math.random() * POSSIBLE.length))]
  }
}


;[test01, test02].forEach((func) => {
  let count = 1000 * 1000
  let now = Date.now()
  for (let i = 0; i < count; i++) {
    func()
  }
  let use_time = Date.now() - now
  console.log('Count = %d, Use Time = %d ms, Cost = %d ms/t', count, use_time, (use_time / count))
})
// node@4.2.2
Count = 1000000, Use Time = 347 ms, Cost = 0.000347 ms/t
Count = 1000000, Use Time = 322 ms, Cost = 0.000322 ms/t

@William17

感谢你的回复

我测试了一下,结果确实与你的例子一样

不使用+=的时候速度变快了,感觉又发现新大陆了,这又是什么原因呢?

@XGHeaven

感谢你的回复

我试了node --prof index.js来跟踪发现使用let的时候调用的Function要比var的时候多,是有你说的可能性

@mzTeamMeatMan

感谢你的回复

但和我问的没什么关系吧。。。

@CoderIvan 具体我也不清楚. 可能在v8上, 但是我在浏览器(chromium@45)里运行你的代码没发现明显性能差异. (当然, 浏览器里的v8版本跟我使用的node的v8版本可能不同)

貌似是v8 对ES5代码有特殊优化吧~

@William17 @magicdawn

现在也就只能这么认为了

@William17 @magicdawn 这个问题我好像在知乎上面看过,是说为了模拟 let 的行为,在外面多包了个匿名 function 。。。?

@alsotang

这里是我刚刚找到的比较可能的答案,http://stackoverflow.com/questions/36623440/let-vs-var-performance-in-nodejs-and-chrome

不过英文水平和时间有限就没详细看了,好像就是你说的那回事,但6.0支持TDZ后就没这回事了(还没实测)

用最新的 nodejs 6.7.0 测试结果类似。 知乎帖子说的很清楚:http://www.zhihu.com/question/47456978/answer/106558397

@CoderIvan 那看来等V8版本升上来就好了

回到顶部