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.push
和Array.join
- 使用数组索引避免
Array.push
,然后使用Array.join
- 直接串接
然后我创建了相同的三个测试,将它们抽象为 StringBuilderConcat
、StringBuilderArrayPush
和 StringBuilderArrayIndex
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 认为我的测试存在缺陷,因此我创建了一个新案例,它不会通过连接相同的字符串来创建大字符串,而是每次迭代都使用不同的字符。字符串连接似乎仍然更快或同样快。让我们运行这些测试。
我建议每个人都应该继续考虑其他方法来测试它,并随时在下面添加指向不同测试用例的新链接。
关于javascript - JavaScript 字符串是不可变的吗?我需要 JavaScript 中的 "string builder"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51185/