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索引来避免Array.push
,然后使用Array.join
直串连接
然后我通过抽象它们创建了相同的三个测试StringBuilderConcat
,StringBuilderArrayPush
并且StringBuilderArrayIndex
http://jsperf.com/string-concat-without-sringbuilder/5请去那里运行测试,这样我们就可以得到一个很好的样本.请注意,我修复了一个小错误,因此测试数据被擦除,一旦有足够的性能数据,我将更新表.转到旧数据表的http://jsperf.com/string-concat-without-sringbuilder/5.
如果您不想关注该链接,请参阅2013年2月21日的部分数据.每次测试的数量都在运行/秒(越高越好)
| Browser | Index | Push | Concat | SBIndex | SBPush | SBConcat | --------------------------------------------------------------------------- | Chrome 71.0.3578 | 988 | 1006 | 2902 | 963 | 1008 | 2902 | | Firefox 65 | 1979 | 1902 | 2197 | 1917 | 1873 | 1953 | | Edge | 593 | 373 | 952 | 361 | 415 | 444 | | Exploder 11 | 655 | 532 | 761 | 537 | 567 | 387 | | Opera 58.0.3135 | 1135 | 1200 | 4357 | 1137 | 1188 | 4294 |
发现
如今,所有浏览器都能很好地处理字符串连接.Array.join
只能帮助Opera
总的来说,Chrome是最快的,在27.0中以1025 ops/sec为单位.比使用Array.join()快10倍
Firefox排在第二位,大约550次操作/秒(但20.0似乎已经退步).Array.join
大约慢了4-5倍.
IE是最快的直接串连接,使用var myString = "abbdef"; myString[2] = 'c'
和它真的很慢trim
.IE 9 slice
不会那么慢,并且所有SB抽象的执行方式几乎相同(可能是因为方法开销)
Opera是"Hello diggity dog"
实际帮助的唯一一个,它的速度是字符串连接的2-3倍.
创建一个StringBuilder来抽象出每个浏览器的性能问题弊大于利.方法调用的开销可能是可以接受的,但趋势似乎是浏览器更聪明地处理字符串连接.只有你的目标受众是Opera才有意义,所以你可以在那里使用Array.join并在其他地方使用String连接(这意味着所有其他浏览器都受到了攻击)
希望别人觉得这很有用
不同的测试用例
由于@RoyTinker认为我的测试存在缺陷,因此我创建了一个新的案例,它不会通过连接相同的字符串来创建大字符串,它会为每次迭代使用不同的字符.字符串连接似乎仍然更快或更快.让我们让这些测试运行起来.
我建议每个人都应该考虑其他方法来测试这个,并随意添加新链接到下面的不同测试用例.
http://jsperf.com/string-concat-without-sringbuilder/7
来自犀牛书:
在JavaScript中,字符串是不可变对象,这意味着它们中的字符可能不会被更改,并且对字符串的任何操作实际上都会创建新字符串.字符串按引用分配,而不是按值分配.通常,当通过引用分配对象时,通过一个引用对对象所做的更改将通过对该对象的所有其他引用可见.但是,由于无法更改字符串,因此您可以对字符串对象进行多次引用,而不必担心字符串值会在您不知情的情况下发生更改
表现提示:
如果必须连接大字符串,请将字符串部分放入数组中并使用该Array.Join()
方法获取整个字符串.对于连接大量字符串,这可以快许多倍.
StringBuilder
JavaScript中没有.