JavaScript:String Concatenation性能下降? Array.join( '')?

时间:2010-05-06 14:10:35

标签: javascript performance

我读过如果我有for循环,我不应该使用字符串仲裁,因为它很慢。如:

for (i=0;i<10000000;i++) {
    str += 'a';
}

相反,我应该使用Array.join(),因为它更快:

var tmp = [];
for (i=0;i<10000000;i++) {
    tmp.push('a');
}
var str = tmp.join('');

但是,我还读到,字符串连接只是Internet Explorer的一个问题,而使用Webkit的Safari / Chrome等浏览器实际上执行速度更快的是使用字符串连接而不是Array.join()

我试图找到字符串连接的所有主要浏览器与Array.join()之间的性能比较,但是找不到它。

因此,什么是更快,更有效的JavaScript代码?使用字符串连接或Array.join()?

3 个答案:

答案 0 :(得分:3)

对于大多数浏览器来说,Array.join()似乎更快。

当前的gen浏览器

FF3        array.join is ~2x faster
Safari 3   array.join ~1.5x faster
Opera 9    += ~3x faster
ie6     array.join ~6x faster
ie7     array.join ~4x faster

下一代浏览器

FF3.1      += array.join equal in speed
Chrome     +=  ~1.25x faster
IE8     array.join ~1.6x faster
Webkit     array.join ~2x faster

此处的测试结果:http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly

答案 1 :(得分:1)

我的感觉是,因为没有“好”的方法来进行功能检查以查看字符串连接是否很慢,并且因为Array.join()在非IE浏览器中并不可怕,所以使用数组方法很好,因为你的网页在任何地方都会表现得很好,你也不会乱七八糟(你可以避免浏览器嗅探)。

现在,如果您正在实施框架或库而不仅仅是网站上的一个或两个功能,那么可能需要进行更精细的调整。

最后,我建议回到谷歌并阅读一些搜索“javascript字符串连接性能”的结果。我发现了几个好的,我只通过了第一个SRP的一半。阅读博客文章中的评论,因为通常你会在那里找到有趣的链接。

答案 2 :(得分:0)

我不仅对字符串连接很感兴趣,而且还对解析也感到好奇。以下是有关array.join,string + =,charAt()和array []的一些结果。

简短摘要

  • 连接数组大约比string + =
  • 快2.5-6倍
  • array []比charAt()快1.5-3倍(并且将字符串拆分为数组不是一个扩展操作)

原始结果

                  Chrome v23    FF 17     IE8
fill array(100k)         43      15       270 ms
join array(100k)         33       5        43 ms
string+=(100k)          223      12       118 ms
charAt(488.89k * 100)   517     462     75467 ms
split(488.89k)           12      34       279 ms
array[](488.89k * 100)  267     323     27343 ms

要测试的HTML代码

<table>
    <col/>
    <col align="right"/>
    <col/>
<script type="text/javascript" >
    function test(what, action) {
        var start = new Date(), end
        document.write("<tr><td>" + what + "</td>")
        action()
        end = new Date()
        document.write("<td>" + (end.getTime() - start.getTime()) + "</td> <td>ms</td></tr>\n")
    }

    var alen = 100000, efAlen, nIter = 100
    var s = ""  // test string for charAt, s[pos]
    var ss = "" // subject ss += "??"
    var as = [] // source for s = as.join("")
    var slen    // slen = s.length
    var a       // a = s.split("")
    var maxSlen = 1000*1000

    test("fill array(" + (alen / 1000) + "k)", function() {
        slen = 0
        for( var i = 0; i < alen; i++ ) {
            var v = "" + i
            slen += v.length
            if( slen < maxSlen )
                efAlen = (i + 1)
            as[i] = v
        }
    })

    test("join array(" + (efAlen / 1000) + "k)", function() {
        s = as.slice(0, efAlen).join("")
        slen = Math.min(s.length, maxSlen)
    })

    test("string+=(" + (efAlen / 1000) + "k)", function() {
        for( var i = 0; i < efAlen; i++ ) {
            ss += as[i]
        }
        if( ss != s )
            document.write("ss.length:" + ss.length + ", s.length:" + s.length)
    })

    test("charAt(" + (slen / 1000) + "k * " + nIter + ")", function() {
        for( var i = 0; i < nIter; i++ ) {
            for( var p = 0; p < slen; p++ ) {
                var c = s.charAt(p)
            }
        }
    })

    test("split(" + (slen / 1000) + "k)", function() {
        a = s.split("")
    })

    test("array[](" + (slen / 1000) + "k * " + nIter + ")", function() {
        for( var i = 0; i < nIter; i++ ) {
            for( var p = 0; p < slen; p++ ) {
                var c = a[p]
            }
        }
    })
</script>
</table>