JavaScript字符串是不可变的吗?我需要一个“字符串构建器”吗?在JavaScript? [英] Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?

查看:107
本文介绍了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.push Array.join

  • 使用数组索引来避免 Array.push ,然后使用 Array.join

  • 直字符串连接

  • Using Array.push and Array.join
  • Using Array indexing to avoid Array.push, then using Array.join
  • Straight string concatenation

然后我通过将它们抽象为 StringBuilderConcat StringBuilderArrayPush 和<$ c来创建相同的三个测试$ c> 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.

如果您不想关注该链接,请参阅2013年2月21日的部分数据。每次测试的数字都在运算/秒(越高越好

Here are some numbers from Feb 21, 2013, if you don't want to follow the link. The number on each test is in operations/second (higher is better)

| Browser          | Index | Push | Concat | SBIndex | SBPush | SBConcat |
---------------------------------------------------------------------------
| Chrome 24.0.1312 | 83    | 87   | 702    | 69      | 87     | 165      |
| Chrome 25.0.1364 | 43    | 47   | 620    | 42      | 42     | 68       |
| Firefox 10.0.10  | 164   | 164  | 533    | 164     | 16     | 421      |
| Firefox 19.0     | 70    | 70   | 259    | 70      | 70     | 186      |
| Exploder 7.0     | 51    | 33   | 58     | 31      | 37     | 45       |
| Exploder 8.0     | 48    | 30   | 58     | 30      | 36     | 36       |
| Exploder 9.0     | 87    | 64   | 95     | 61      | 61     | 61       |
| Opera 12.14      | 125   | 154  | 66     | 106     | 137    | 63       | 

调查结果


  • 如今,所有浏览器都能很好地处理字符串连接。 Array.join 仅帮助Opera

整体而言,Chrome最快,在27.0中以1025 ops / sec计时。比使用Array.join()快10倍

Overall, Chrome is fastest, clocking 1025 ops/sec in 27.0. 10 times faster than using Array.join()

Firefox排在第二位,大约550 ops / sec(但20.0似乎已经退步)。 Array.join 慢大约4-5倍。

Firefox is in second place at around 550 ops/sec (but 20.0 seems to have regressed). Array.join is about 4-5 times slower.

使用直接串联连接时IE速度最快,使用 Array.join Array.push ,这真的很慢。 IE 9使 Array.join 不会那么慢,并且所有SB抽象的执行方式几乎相同(可能是因为方法开销)

IE is fastest with straight string concatenation, it's really slow using Array.join and Array.push. IE 9 makes Array.join not be so slow, and all the SB abstractions perform almost the same way (probably because of the method overhead)

Opera是唯一一个 Array.join 实际上有帮助的人,它的速度是字符串连接速度的2-3倍。

Opera is the only one where the Array.join actually helps, it's 2-3 times as fast as string concatenation.

创建一个StringBuilder来抽象出每个浏览器的性能问题弊大于利。方法调用的开销可能是可以接受的,但趋势似乎是浏览器更聪明地处理字符串连接。只有你的目标受众是Opera才有意义,所以你可以在那里使用Array.join并在其他地方使用字符串连接(这意味着所有其他浏览器都会受到影响)

Creating a StringBuilder to abstract away each browser's performance issues does more harm than good. The overhead of method calls may be acceptable but the tendency seems to be that browsers are handling string concatenation more smartly. It would only make sense if your target audience is Opera, so you can use Array.join there and use String concatenation everywhere else (this means all the other browsers are taking a hit)

希望别人认为这个有用

不同的测试用例

由于@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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆