javascript - JavaScript 字符串是不可变的吗?我需要 JavaScript 中的 "string builder"吗?

标签 javascript string

javascript 使用不可变字符串还是可变字符串?我需要一个“字符串生成器”吗?

最佳答案

它们是不可变的。您不能使用 var myString = "abbdef"; 之类的方式更改字符串中的字符。 myString[2] = 'c'. trim等字符串操作方法, slice返回新字符串。

同理,如果你有两个对同一个字符串的引用,修改一个不会影响另一个

let a = b = "hello";
a = a + " world";
// b is not affected

但是,我一直听到 Ash 在他的回答中提到的内容(使用 Array.join 进行连接更快),所以我想测试连接字符串的不同方法并将最快的方法抽象为 StringBuilder。我写了一些测试来看看这是不是真的(不是!)。

这是我认为最快的方法,尽管我一直认为添加方法调用可能会使它变慢...

function StringBuilder() {
    this._array = [];
    this._index = 0;
}

StringBuilder.prototype.append = function (str) {
    this._array[this._index] = str;
    this._index++;
}

StringBuilder.prototype.toString = function () {
    return this._array.join('');
}

以下是性能速度测试。他们三个都创建了一个由 "Hello diggity dog" 十万次连接成一个空字符串组成的巨大字符串。

我创建了三种类型的测试

  • 使用 Array.pushArray.join
  • 使用数组索引避免Array.push,然后使用Array.join
  • 直接串接

然后我创建了相同的三个测试,将它们抽象为 StringBuilderConcatStringBuilderArrayPushStringBuilderArrayIndex http://jsperf.com/string-concat-without-sringbuilder/5请去那里进行测试,以便我们得到一个很好的样本。请注意,我修复了一个小错误,因此测试数据被删除,一旦有足够的性能数据,我将更新表。转至 http://jsperf.com/string-concat-without-sringbuilder/5对于旧数据表。

这里有一些数字(Ma5rch 2018 中的最新更新),如果您不想点击链接。每个测试的数字是 1000 次操作/秒(越高越好)

<头>
浏览器 索引 连接 SBIndex SBPush SBConcat
Chrome 71.0.3578 988 1006 2902 963 1008 2902
火狐65 1979 1902 2197 1917 1873 1953
边缘 593 373 952 361 415 444
爆炸者 11 655 532 761 537 567 387
歌剧 58.0.3135 1135 1200 4357 1137 1188 4294

调查结果

  • 如今,所有常青浏览器都能很好地处理字符串连接。 Array.join 只对 IE 11 有帮助

  • 总体来说,Opera 是最快的,是 Array.join 的 4 倍

  • Firefox 排在第二位,Array.join 在 FF 中仅稍慢一点,但在 Chrome 中则慢得多 (3x)。

  • Chrome 排第三,但字符串 concat 比 Array.join 快 3 倍

  • 创建 StringBuilder 似乎对性能影响不大。

希望其他人觉得这很有用

不同的测试用例

由于@RoyTinker 认为我的测试存在缺陷,因此我创建了一个新案例,它不会通过连接相同的字符串来创建大字符串,而是每次迭代都使用不同的字符。字符串连接似乎仍然更快或同样快。让我们运行这些测试。

我建议每个人都应该继续考虑其他方法来测试它,并随时在下面添加指向不同测试用例的新链接。

http://jsperf.com/string-concat-without-sringbuilder/7

关于javascript - JavaScript 字符串是不可变的吗?我需要 JavaScript 中的 "string builder"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51185/

相关文章:

javascript - ng-style 未应用在 Angular ng-repeat

javascript - 循环遍历多维数组

javascript - Internet Explorer - "Object doesn' t 支持这种属性......”

c - 指针:为什么输出是 6?

javascript - 加载一个 .html 页面,其中应包含 .php 文件中的一些数据

c# - 从 .cs 调用 Javascript 函数

c++ - 错误:return type specified for 'operator std::string {aka std::__cxx11::basic_string<char>}'

javascript - 如何在 JavaScript 中解析日期时间字符串的日期部分?

c++ - 构建正确的类

java - ArrayList之数组删除元素及split方法