【问题标题】:Does concatenation create garbage?串联会产生垃圾吗?
【发布时间】:2015-05-23 21:17:04
【问题描述】:

我确实在网上搜索过这个信息,有人说 yes 因为 javascript 必须创建一个新的字符串对象来存储连接的结果,有人说 no 因为字符串不收集对象。

也许这取决于上下文。例如,如果我有一个对象数组,例如

animals["blue_dog","red_dog","yellow_cat","red_bird","green_bird"...]

我有一个带有animalcolor 参数的函数,在这个函数中我会像这样访问我的对象:

animals[animal+"_"+color]

大多数时候我在绘制文本时会进行连接,这显然不会在每帧中发生很多次。所以即使变成垃圾,也无足轻重。但是当使用串联作为对象的键时,由于循环,这种串联可能每帧发生一千次,然后这可能会成为一个问题。

【问题讨论】:

  • 请提供一些工作代码示例。
  • 数组用整数索引。 animals[animal+"_"+color] 是引用对象属性的格式。
  • 即使这是一个问题(不是),你的选择是什么?
  • var array = { "blue-dog": 1, "red-dog": 3, "red-fox": 2, "blue-fox": 4 } var heads, tails, i; heads = ["blue", "red"]; tails = ["dog", "fox"]; var CONST = 1000000; for( i = 0 ; i < CONST; i++ ) { array[heads[i%2] + '-' + tails[i%2]]; }
  • 在 Chrome 中使用活动的 Profiler 尝试此代码以检查您的理论。

标签: javascript garbage-collection


【解决方案1】:

执行animals[color + "_" + animal] 之类的操作会为访问对象创建一个临时值。该临时值将由垃圾收集器或在块/函数调用结束时收集(取决于实现)。

我的假设(基于我自己在使用编译器方面的经验)是,由于结果没有存储在变量中,因此它将被放置在堆栈上并在函数完成后释放。但是,这又取决于引擎的编写方式。

我绝不是编译器方面的专家。

【讨论】:

    【解决方案2】:

    可能会或可能不会,取决于编译器的优化程度。

    这个a + b + c(a + b) + c,所以你有两个串联。 (a + b) 的结果将是一个临时对象(此处为字符串)。那个临时的就是垃圾。

    对于给定的表达式,这种形式a.concat(b,c) 在概念上更好。它原则上不需要中间临时对象。

    【讨论】:

      【解决方案3】:

      根据我的经验,连接字符串肯定会产生垃圾。我有一个场景,我在一个大表中有很多单元格,每个单元格都可以分配一个不同的 css 类(来自一组可能 30 种不同组合的组合)。以正常方式执行此操作:

      const class = group + empty + active;

      会产生很多垃圾。我创建了一个 memoized 函数,它接收一个位掩码作为参数,它会生成类字符串并以这种方式摆脱垃圾。

      这个回复很好地列出了要避免的事情:

      https://stackoverflow.com/a/18411275

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多