+运算符的性能比StringBuffer.append()差


91

在我的团队中,我们通常像这样进行字符串连接:

var url = // some dynamically generated URL
var sb = new StringBuffer();
sb.append("<a href='").append(url).append("'>click here</a>");

显然,以下内容更具可读性:

var url = // some dynamically generated URL
var sb = "<a href='" + url + "'>click here</a>";

但是JS专家声称+运算符的性能不如运算符StringBuffer.append()。这是真的吗?


92
javascript中没有StringBuffer
Tomas 2010年

7
唐,您是在指Java吗?
詹姆斯·麦克马洪

我的经验是[].join('')显示出一些真正的行为,所以我回到+:-/
martyglaubitz 2012年

1
我知道这里的基本问题是关于字符串连接的,但是在创建这样的html元素时应格外小心。如果url包含'或,则示例可能会中断\n
styfle

Answers:


46

Internet Explorer是当今世界上唯一遭受此困扰的浏览器。(版本5、6和7的速度变慢。8不会出现相同的降级。)而且,IE越长,字符串越长,速度就越慢。

如果您要连接的字符串很长,则一定要使用array.join技术。(或者,一些StringBuffer包装器,以提高可读性。)但是,如果您的字符串较短,请不要打扰。


102

您的示例不是一个很好的示例,因为性能不太可能出现显着差异。在您的示例中,可读性应胜过性能,因为一个性能对另一个性能的提高可忽略不计。数组(StringBuffer)的好处只有在您进行许多合并时才显而易见。即使那样,您的行驶里程也可能很大程度上取决于您的浏览器。

这是一份详细的性能分析,显示了在许多不同浏览器中使用所有不同JavaScript串联方法的性能。字符串性能分析

join()一次,concat()一次,join()表示,+ =表示,concat()表示

更多:
Ajaxian >> IE中的字符串性能:Array.join与+ =续


9
关于图形,如果不明显的话;越低越好。
Teekin 2010年

1
“首先要考虑到IE7的性能改进,在进行大规模字符串操作时,我们不再需要考虑使用替代路径;在迭代情况下使用Array.join不会比在相同情况下使用+ =带来主要优势。此外,与IE6的差异很小,足以使您不必为该特定版本分叉。”
克里斯S

2
@克里斯,那不是真的。比较IE7中的这两个小提琴:jsfiddle.net/9uS4n/5(快速)与jsfiddle.net/9uS4n/2(慢)。使用该join()技术的性能似乎至少提高了1000倍。
柯克·沃尔,

很好的解释。:也请查看本 iliadraznin.com/2012/03/...
will824

37

是的,这是真的,但您不必在意。选择一个更容易阅读的语言。如果您必须对您的应用进行基准测试,请关注瓶颈。

我猜想字符串连接不会成为您的瓶颈。


31

同意Michael Haren的观点

如果性能确实是一个问题,也要考虑使用数组和联接。

var buffer = ["<a href='", url, "'>click here</a>"];
buffer.push("More stuff");
alert(buffer.join(""));

3
我知道已经选择了正确的答案,但是这个答案有一个更有用的示例。
Jason Sperske'4

1
哇,哇 比较IE7中的这两个小提琴:jsfiddle.net/9uS4n/5(快速)与jsfiddle.net/9uS4n/2(慢)。使用这种技术的性能似乎至少提高了1000倍。
柯克·沃尔,

@KirkWoll:将来可能想使用jsPerf,以便我们可以轻松比较结果。
rvighne 2014年

我最近也一直在这样做,类似于.NET StringBuilder的代码风格,var sb = []; sb.push(“ section 1”); sb.push(“ section 2”); 返回sb.join('');
山姆·琼斯


18

试试这个:

var s = ["<a href='", url, "'>click here</a>"].join("");

好吧,您在答案中链接到的帖子专门试图反驳我的答案所暗示的Array.join的“神话”。所以也许不是。我只是发布了我认为在实践中更快的内容。
拉胡尔

喜欢这种字符串连接的方法。
bkwdesign 2014年

8

就像一些用户已经注意到的那样:这与小字符串无关。

Firefox,Safari或Google Chrome中的新JavaScript引擎也进行了优化

"<a href='" + url + "'>click here</a>";

快如

["<a href='", url, "'>click here</a>"].join("");

8

JavaScript没有本地的StringBuffer对象,因此我假设这是您正在使用的库中的内容,或者是不寻常的宿主环境(即不是浏览器)的功能。

我怀疑一个库(用JS编写)会更快地产生任何东西,尽管原生StringBuffer对象可能会。可以使用探查器找到明确的答案(如果您在浏览器中运行,则Firebug将为您提供Firefox中JS引擎的探查器)。


6

用克努斯的话来说,“过早的优化是万恶之源!” 两种方式之间的小偏差最终都不会产生太大影响。我会选择可读性更高的一种。


1
传统上,StringBuffer用于连接,因为前者的时间复杂度为O(N),而后者为O(N ^ 2),因此,对于大N(对于小N而言),这种差异是很明显的。在任何情况下,取决于所使用的环境,O(N ^ 2)场景在JavaScript中都可能不是这种情况。
redcalx

4

易于阅读的方法在查看代码时节省了人类可察觉的时间,而“更快”的方法仅在人们浏览页面时浪费了难以察觉且可能微不足道的时间。

我知道这则帖子很me脚,但是我不小心发布了完全不同的内容,以为这是一个不同的主题,而且我不知道如何删除该帖子。我的错...



2

我喜欢使用功能样式,例如:

function href(url,txt) {
  return "<a href='" +url+ "'>" +txt+ "</a>"
}

function li(txt) {
  return "<li>" +txt+ "</li>"
}

function ul(arr) {
  return "<ul>" + arr.map(li).join("") + "</ul>"
}

document.write(
  ul(
    [
      href("http://url1","link1"),
      href("http://url2","link2"),
      href("http://url3","link3")
    ]
  )
)

这种样式看起来可读且透明。它导致创建实用程序,该实用程序减少了代码的重复。

这也倾向于自动使用中间字符串。


1

据我所知,每个串联都意味着内存重新分配。因此,问题不在于操作员曾经这样做过,解决方案是减少级联数量。例如,如果可以,请在迭代结构之外进行串联。


这实际上不是一个坏建议,我不知道为什么它被否决了这么多。我知道它不能回答特定问题,但是它应该是公认的好建议。
眼睑失明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.