var s = '', ok = ' h dfb ds84 78sgf ydf hjb////**', lc = 0, cc = 0
for (var i = 0; i < 300000; i++) {
s += ok[Math.floor(Math.random() * ok.length)]
}
console.time('[]')
for (var i = 0; i < s.length; i++) {
if (s[i] == '/' && s[i+1] == '/') lc++, i++
if (s[i] == '/' && s[i+1] == '*') cc++, i++
}
console.timeEnd('[]')
/*
console.time('charAt')
for (var i = 0; i < s.length; i++) {
if (s.charAt(i) == '/' && s.charAt(i+1) == '/') lc++, i++
if (s.charAt(i) == '/' && s.charAt(i+1) == '*') cc++, i++
}
console.timeEnd('charAt')
*/
console.time('regex')
var rlc = (s.match(/\/\//g) || []).length;
var rcc = (s.match(/\/\*/g) || []).length;
console.timeEnd('regex')
console.log(lc, cc, rlc==lc, rcc==cc)
为什么str.charAt()始终显示比str []提高1.6的性能?他们不应该以同样的方式做同样的事情吗? []会做一些影响速度的额外检查或转换吗?或者它是关于我的代码?
此外,为什么str.charCodeAt(i) == 42
比str.charAt(i) == '/'
快10%?从C / C ++的角度来看,它完全没有意义。
更新:我把完整的测试代码放在这里。
UPDATE2:我必须说这是使用Node.js ver 0.11.4
观察到的http://jsperf.com/brackets-vs-charat3 此测试用例显示较小的差异。 charAt()在Chrome 37中慢了6%,在Firefox 33中慢了1%。所有Ubuntu 64。
更新3,因为这似乎是Node.js问题,我添加了node.js标记
答案 0 :(得分:2)
他们不应该以同样的方式做同样的事情吗?
没有。除了明显不同的方式,他们不会做同样的事情。查看spec for charAt
和for []
on strings。
[]是否会进行一些影响速度的额外检查或转换?
显然。不同之处在于charAt
需要将其操作数强制转换为字符串,[]
不需要这样做。此外,charAt
将返回空字符串以进行越界访问,而[]
将返回undefined。而且大多数情况下,[]
需要检查给定的属性名称是否真的是一个整数,以及字符串对象上是否存在具有该名称的实际属性。
还是我的代码呢?
您的代码看起来很好。
此外为什么str.charCodeAt(i)== 42比str.charAt(i)=='/'快10%?从C / C ++的角度来看,它完全没有意义。
请注意,JavaScript没有char
数据类型。 '/'
是一个长度为1的字符串。看起来它没有很好地优化(或者很容易),并且整数 1 比较比字符串快比较。
1:大多数数字,虽然“每个规范”是64位浮点数,但在V8中表示为31位整数。
答案 1 :(得分:-2)
引用Crockford的“JavaScript:the Good Parts”,打开Chap 6,Arrays的段落:
...数组可以是非常快速的数据结构。不幸的是,JavaScript没有像这种数组那样的东西。 相反,JavaScript提供了一个具有类似数组特征的对象。它将数组下标转换为用于创建属性的字符串。它比真正的阵列慢得多......
因此,在C或Java中,arr [2]是指向内存位置的直接指针,因此应具有非常快的性能,在JS中,arr [2]实际上意味着“将数字2转换为字符串'2' ,然后将其哈希以用作对象中的查找。“
散列查找仍然非常快,但不如真正的数组快。添加它需要将数字转换为字符串然后进行散列,并且您会看到性能损失。
另一方面,我认为str.charAt(2)
是一个本机函数,可能正在进行真正的数组查找。