【问题标题】:Array Join vs String Concat数组连接与字符串连接
【发布时间】:2011-11-09 22:17:17
【问题描述】:

哪种方法更快?

数组连接:

var str_to_split = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
var myarray = str_to_split.split(",");

var output=myarray.join("");

字符串连接:

var str_to_split = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
var myarray = str_to_split.split(",");

var output = "";
for (var i = 0, len = myarray.length; i<len; i++){
    output += myarray[i];
}

【问题讨论】:

  • 取决于你想要什么。 String 方法稍微简单一些。 Array join 方式可能会快一些(你可以在 jsperf.com 上测试)。
  • for 循环到底是干什么用的?只是复制或您正在处理它。有更快的方法来复制数组。
  • epascarello,它们只是测试这两种方法的愚蠢示例
  • 我记得几年前读过一些文章引用性能统计数据来证明数组方法比字符串连接更快,但即使在那时它也因浏览器而异。在我看来,每次下一代浏览器问世时,这些类型的性能都会发生逆转。
  • 目前在 Chrome 53 和 Firefox 48 中,迭代速度比数组连接 (link) 快 1.5 倍以上

标签: javascript arrays performance join connection-string


【解决方案1】:

我可以肯定地说使用Array.join() 更快。我已经编写了几段 JavaScript 代码,并通过删除字符串操作以支持数组来显着提高性能。

【讨论】:

    【解决方案2】:

    ECMAScript 中的字符串连接速度更快。这是我创建的一个基准测试:

    http://jsben.ch/#/OJ3vo

    【讨论】:

    • 更新:我发现了一些重要的事情,1)我们在连接示例中不必要地重新创建了数组,2)如果我们存储数组长度以防止检查每个数组的长度会更好迭代
    • @ajax333221: “我们在连接示例中不必要地重新创建了数组”创建数组以便连接它是重点。您更新的 jsperf 将苹果与橙子进行比较。如果您已经有一个数组,是的,join 更快。但是人们比较的是创建一个数组只是为了加入它,而不是做字符串连接。完全不同的鱼壶。
    • Apples to apples:将不同长度的字符串连接 2000 次,或者在数组中构建并执行 join,或者使用字符串 concat。 jsperf.com/yet-another-array-vs-concat Concat 在性能方面赢得了现代引擎的青睐,当然,在可读性/可维护性/可调试性方面始终获胜。当我 10 年前尝试这个时,阵列的性能稍好一些。现在不是这样了。
    • 我认为 jsben.ch 网站可能有问题。与 jsperf.com 的结果不一致:stackoverflow.com/questions/44612083/…
    • 2018, FF v59, 上述链接的结果 -> array join (fastest!)
    【解决方案3】:

    根据this Google document titled 'Optimizing JavaScript code',字符串 concat 比数组连接要慢,但显然对于现代 Javascript 引擎而言并非如此。

    我制作了他们在文档中使用的 a benchmark for the Fibonacci test example,它表明连接(粘合)字符串的速度几乎是使用 Array join 的 4 倍。

    【讨论】:

    • 基准测试不是很好,因为您不仅将字符串连接与连接数组进行比较,而且在连接情况下也在基准测试中创建一个新数组。
    【解决方案4】:

    从 2011 年到现代...

    参见下面的join rewrite using string concatenation,它比标准实现慢了多少。

    // Number of times the standard `join` is faster, by Node.js versions:
    // 0.10.44: ~2.0
    // 0.11.16: ~4.6
    // 0.12.13: ~4.7
    // 4.4.4: ~4.66
    // 5.11.0: ~4.75
    // 6.1.0: Negative ~1.2 (something is wrong with 6.x at the moment)
    function join(sep) {
        var res = '';
        if (this.length) {
            res += this[0];
            for (var i = 1; i < this.length; i++) {
                res += sep + this[i];
            }
        }
        return res;
    }
    

    道德是 - 不要手动连接字符串,始终使用标准 join

    【讨论】:

    • 我遇到了这个话题,其他答案可能在 2011 年是正确的,但此时加入确实更好。
    【解决方案5】:

    展开运算符,用三个连续的点 ( ... ) 编写,是 ES6 中的新功能,让您能够将可迭代对象展开或展开为多个元素。

    const books = ["Don Quixote", "The Hobbit", "Alice in Wonderland", "Tale of Two Cities"];
    console.log(...books);

    版画:唐吉诃德霍比特人爱丽丝梦游仙境的两个城市的故事

    【讨论】:

    • 这仅在您的函数接受多个 (...rest) 参数时才有效。 console.log 就是这样一个例子。但是,这并不总是回答 OP 的问题,因为您可能正在使用只接受 1 个字符串参数的函数,在这种情况下扩展运算符将失败。
    【解决方案6】:

    对于固定长度的数值数组,手动连接速度更快。

    Here's a JSPerf test that tests these two operations:

    zxy.join('/')
    
    // versus
    
    zxy[0] + '/' + zxy[1] + '/' + zxy[2]
    
    // given the array
    
    zxy = [1, 2, 3]
    
    // resulting in the string '0/1/2'
    

    结果:使用 Chrome 64.0.3282.186,Array.join 的速度降低了 46%。

    【讨论】:

    • 现在使用 Chrome 65.0.3325.181,Array.join 慢了 71%。
    【解决方案7】:

    这取决于:

    铬 79.0.3945

    Array Join 速度慢 30%

    火狐 71.0.0

    字符串 Concat 慢 90%

    https://jsperf.com/lin-array-join-vs-string-concat

    【讨论】:

      【解决方案8】:

      当字符串数组已经存在时,'Join' 会更快。真正的比较是比较:

      1. 将元素推入数组,然后加入它们以构建字符串
      2. 每次不使用数组连接字符串

      对于少量的迭代和字符串,使用 push-and-join 或 concatenate 都没有关系。但是,对于大量字符串,数组推送和连接似乎在 chrome 和 firefox 中都更快

      这里是 10 到 1000 万个字符串的代码和测试结果:

      铬:

      strings 10
      join-only: 0.01171875 ms
      push-join: 0.137939453125 ms
      concatenate: 0.01513671875 ms
      strings 100
      join-only: 0.01416015625 ms
      push-join: 0.13427734375 ms
      concatenate: 0.0830078125 ms
      strings 1000
      join-only: 0.048095703125 ms
      push-join: 0.47216796875 ms
      concatenate: 0.5517578125 ms
      strings 10000
      join-only: 0.465087890625 ms
      push-join: 5.47314453125 ms
      concatenate: 4.9619140625 ms
      strings 100000
      join-only: 7.6240234375 ms
      push-join: 57.37109375 ms
      concatenate: 67.028076171875 ms
      strings 1000000
      join-only: 67.666259765625 ms
      push-join: 319.3837890625 ms
      concatenate: 609.8369140625 ms
      strings 10000000
      join-only: 824.260009765625 ms
      push-join: 3207.129150390625 ms
      concatenate: 5959.56689453125 ms
      

      火狐:

      strings 10
      join-only: 0ms
      push-join: 1ms
      concatenate: 0ms
      strings 100
      join-only: 0ms
      push-join: 0ms
      concatenate: 0ms
      strings 1000
      join-only: 0ms
      push-join: 1ms
      concatenate: 0ms
      strings 10000
      join-only: 1ms
      push-join: 2ms
      concatenate: 0ms
      strings 100000
      join-only: 5ms
      push-join: 11ms
      concatenate: 8ms
      strings 1000000
      join-only: 39ms
      push-join: 88ms
      concatenate: 98ms
      strings 10000000
      join-only: 612ms
      push-join: 1095ms
      concatenate: 3249ms
      

      要测试的代码:

      for (var n = 10; n <= 10000000; n*=10) {
          
          var iterations = n;
      
          console.log("strings", iterations);
          console.time("push-join");
          arr = [];
          for (var i = 0; i< iterations; i++) {
              arr.push("a b c d e f g h i j k l m");
          }
          console.time("join-only");
          content = arr.join(",");
          console.timeEnd("join-only");
          console.timeEnd("push-join");
      
          content = "";
      
          console.time("concatenate");    
          for (var i = 0; i< iterations; i++) {
              content += "a b c d e f g h i j k l m";
          }
          console.timeEnd("concatenate");
      
      }
      

      【讨论】:

        【解决方案9】:

        2021 年测试

        见下面的代码。结果:

        Firefox:在常规使用中,push+join 比字符串 concat 慢 80%

        Chrome:在常规使用中,push+join 比字符串 concat 慢 140%

        function test(items = 100, rep = 1000000) {
          let str
        
          console.time('concat')
          for (let r = 0; r < rep; r++) {
            str = ''
            for (let i = 0; i < items; i++) {
              str += i
            }
          }
          console.timeEnd('concat')
        
          console.time('push+join')
          for (let r = 0; r < rep; r++) {
            const arr = []
            for (let i = 0; i < items; i++) {
              arr.push(i)
            }
            str = arr.join('')
          }
          console.timeEnd('push+join')
        }
        

        【讨论】:

        • +1 以获得更新的答案,但实际上,当我回顾 10 年并且担心性能时,我感到畏缩,而这一切都与代码维护有关
        猜你喜欢
        • 2015-01-13
        • 1970-01-01
        • 2012-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-16
        相关资源
        最近更新 更多