字符串是不可变的吗

字符串是不可变的吗

本文介绍了JavaScript 字符串是不可变的吗?我需要一个“字符串生成器"吗?在 JavaScript 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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.pushArray.join
  • 使用数组索引避免Array.push,然后使用Array.join
  • 直接字符串连接

然后我通过将它们抽象为 StringBuilderConcatStringBuilderArrayPushStringBuilderArrayIndex 来创建相同的三个测试 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)

浏览器索引连接SBIndexSBpushSBConcat
Chrome 71.0.35789881006290296310082902
火狐 65197919022197191718731953
边缘593373952361415444
炸药11655532761537567387
Opera 58.0.3135113512004357113711884294

发现

  • 现在,所有常绿浏览器都可以很好地处理字符串连接.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 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 14:28