问题描述
javascript 使用不可变字符串还是可变字符串?我需要字符串生成器"吗?
Does javascript use immutable or mutable strings? Do I need a "string builder"?
推荐答案
它们是不可变的.您不能使用类似 var myString = "abbdef"; 之类的内容更改字符串中的字符.myString[2] = 'c'
.trim
, slice
返回新的字符串.
They are immutable. You cannot change a character within a string with something like var myString = "abbdef"; myString[2] = 'c'
. The string manipulation methods such as trim
, slice
return new strings.
同理,如果同一个字符串有两个引用,修改一个不会影响另一个
In the same way, if you have two references to the same string, modifying one doesn't affect the other
let a = b = "hello";
a = a + " world";
// b is not affected
但是,我一直听到 Ash 在他的回答中提到的内容(使用 Array.join 进行连接速度更快),因此我想测试连接字符串的不同方法并将最快的方法抽象为 StringBuilder.我写了一些测试来看看这是否属实(不是!).
However, I've always heard what Ash mentioned in his answer (that using Array.join is faster for concatenation) so I wanted to test out the different methods of concatenating strings and abstracting the fastest way into a StringBuilder. I wrote some tests to see if this is true (it isn't!).
这是我认为最快的方法,尽管我一直认为添加方法调用可能会使其变慢...
This was what I believed would be the fastest way, though I kept thinking that adding a method call may make it slower...
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"
连接十万次组成一个空字符串.
Here are performance speed tests. All three of them create a gigantic string made up of concatenating "Hello diggity dog"
one hundred thousand times into an empty string.
我创建了三种类型的测试
I've created three types of tests
- 使用
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 用于旧数据表.
Then I created the same three tests by abstracting them into StringBuilderConcat
, StringBuilderArrayPush
and StringBuilderArrayIndex
http://jsperf.com/string-concat-without-sringbuilder/5 Please go there and run tests so we can get a nice sample. Note that I fixed a small bug, so the data for the tests got wiped, I will update the table once there's enough performance data. Go to http://jsperf.com/string-concat-without-sringbuilder/5 for the old data table.
这里有一些数字(Ma5rch 2018 的最新更新),如果您不想点击链接.每次测试的数量是 1000 次操作/秒(越高越好)
Here are some numbers (Latest update in Ma5rch 2018), if you don't want to follow the link. The number on each test is in 1000 operations/second (higher is better)
浏览器 | 索引 | 推 | 连接 | 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 |
Opera 58.0.3135 | 1135 | 1200 | 4357 | 1137 | 1188 | 4294 |
发现
现在,所有常绿浏览器都可以很好地处理字符串连接.
Array.join
只对 IE 11 有帮助
Nowadays, all evergreen browsers handle string concatenation well.
Array.join
only helps IE 11
总的来说,Opera 是最快的,是 Array.join 的 4 倍
Overall, Opera is fastest, 4 times as fast as Array.join
Firefox 次之,Array.join
在 FF 中仅稍微慢一点,但在 Chrome 中慢得多(3 倍).
Firefox is second and Array.join
is only slightly slower in FF but considerably slower (3x) in Chrome.
Chrome 排第三,但字符串连接比 Array.join 快 3 倍
Chrome is third but string concat is 3 times faster than Array.join
创建一个 StringBuilder 似乎对性能影响不大.
Creating a StringBuilder seems to not affect perfomance too much.
希望其他人觉得这有用
不同的测试用例
由于@RoyTinker 认为我的测试有缺陷,所以我创建了一个新案例,它不会通过连接相同的字符串来创建大字符串,它为每次迭代使用不同的字符.字符串连接似乎仍然更快或同样快.让我们运行这些测试.
Since @RoyTinker thought that my test was flawed, I created a new case that doesn't create a big string by concatenating the same string, it uses a different character for each iteration. String concatenation still seemed faster or just as fast. Let's get those tests running.
我建议每个人都应该继续考虑其他测试方法,并随时添加指向下面不同测试用例的新链接.
I suggest everybody should keep thinking of other ways to test this, and feel free to add new links to different test cases below.
http://jsperf.com/string-concat-without-sringbuilder/7
这篇关于JavaScript 字符串是不可变的吗?我需要一个“字符串生成器"吗?在 JavaScript 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!