javascript使用不可变字符串还是可变字符串?我需要"字符串生成器"吗?

推荐答案

它们是不变的.不能用var myString = "abbdef"; myString[2] = 'c'这样的数字来更改字符串中的字符.字符串操作方法(如trimslice)返回新字符串.

同样,如果对同一字符串有两个引用,修改其中一个不会影响另一个

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('');
}

以下是性能速度测试.这三个元素都创建了一个巨大的字符串,由10万次连接组成一个空字符串.

我创建了三种类型的测试

  • 使用Array.pushArray.join
  • 使用数组索引避免Array.push,然后使用Array.join
  • 直串串联

然后我创建了同样的三个测试,将它们抽象为StringBuilderConcatStringBuilderArrayPushStringBuilderArrayIndex.http://jsperf.com/string-concat-without-sringbuilder/5请go 那里运行测试,这样我们就可以得到一个好的样本.请注意,我修复了一个小错误,因此测试数据被删除,一旦有足够的性能数据,我将更新该表.对于旧数据表,请转至http://jsperf.com/string-concat-without-sringbuilder/5.

这里有一些数字(2018年Ma5rch的最新更新),如果你不想关注这个链接的话.每次测试的次数为higher is better0次/秒(higher is better)

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

Findings

  • 如今,所有evergreen浏览器都能很好地处理字符串连接.Array.join只对IE 11有帮助

  • 总体而言,Opera速度最快,是Array的4倍.参加

  • Firefox排在第二位,Array.join在FF中的速度略慢,但在Chrome中的速度要慢很多(3倍).

  • Chrome位居第三,但String Concat的速度是Array.Join的3倍

  • 创建StringBuilder似乎不会对性能产生太大影响.

希望其他人觉得这个有用

Different Test Case

因为@RoyTinker认为我的测试有缺陷,所以我创建了一个新的 case ,它不会通过连接相同的字符串来创建大字符串,它为每次迭代使用不同的字符.字符串连接看起来仍然更快,或者说同样快.让我们开始那些测试吧.

我建议每个人都应该继续思考其他方法来测试这一点,并且可以在下面为不同的测试用例添加新的链接.

http://jsperf.com/string-concat-without-sringbuilder/7

Javascript相关问答推荐

如何确保滚动时响应式图像保持在文本图像布局中的顶部?

我可以获取所有包含@的超链接,然后在新选项卡中打开它们吗?

使用Angular 17计算从生日日期起的年、月、天

序列化我的数据并发送httpPost请求后,控制器收到空参数

如何将剧作家请求对象转换为字符串,因为它只提供promise ?

无法在page. evalve()内部使用外部函数

如何在不使用类型化数组的情况下将32位浮点数按位转换为整值?

一次仅播放一个音频

使用JavaScript单击上一个或下一个特定按钮创建卡滑动器以滑动单个卡

是否有方法在OpenWeatherMap API中获取过go 的降水数据?

materialized - activeIndex返回-1

node TS:JWT令牌签名以验证客户端和后台问题之间的身份验证

Google图表时间轴—更改hAxis文本 colored颜色

手机上的渲染错误文本必须在文本组件中渲染,但在浏览器上没有问题<><>

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

如何在ASP.NET JavaScript中使用Google Charts API仅对绘制为负方向的条形图移动堆叠条形图标签位置

从页面到应用程序(NextJS):REST.STATUS不是一个函数

SPAN不会在点击时关闭模式,尽管它们可以发送日志(log)等

在SHINY R中的嵌套模块中,不能使用Java代码

触发异步函数后不能显示数据