ECMAScript
的字符串可以通过+
进行自加连接。
let str1 = "";
str1 += "str1 ";
这个过程需要完成以下步骤:
- 创建存储 "hello " 的字符串。
- 创建存储 “world” 的字符串。
- 创建存储连接结果的字符串。
- 把 str的当前内容复制到结果中。
- 把 “world” 复制到结果中。 更新 str,使它指向结果。
每一次的字符串+
都需要完成第2到第6个步骤,这种消耗在庞大的数据基数下是不可忽视的。
我在复习W3school中ECMAScript 定义类或对象的内容时,看到了对于字符串连接性能优化的解决方案,特此整理记录一下。
首先,我们来看一下这个解决方法:
let str2 = [];
str2.push("str2 ");
let str2Result = str2.join("");
在这个过程中需要完成的步骤如下:
- 创建存储结果的字符串
- 把每个字符串复制到结果中的合适位置
我们可以明显的发现,这个步骤少了非常多。那么,我们来看一下这两种方法在1000000次的累加操作中,需要消耗的时间:
count = 1000000;
console.time("str1");
let str1 = "";
for (let index = 0; index < count; index++) {
str1 += "str1 ";
}
console.timeEnd("str1");
console.time("str2");
let str2 = [];
for (let index = 0; index < count; index++) {
str2.push("str2 ");
}
let str2Result = str2.join("");
console.timeEnd("str2");
执行结果为:
str1: 105.918ms
str2: 71.861ms
很明显,使用数组对字符串的连接进行操作,更加节省资源。
但是单纯的使用数组方法,会让代码的可读性降低。为了对上层更加友好,我们可以将这个功能封装一下。
function StringBuffer(str) {
if (!str) {
str = "";
} else if (typeof str !== "string") {
throw new Error("必须是字符串");
}
this.string = [str];
if (typeof StringBuffer._initialized === "undefined") {
// 执行字符串插入数组的操作
StringBuffer.prototype.append = function (str) {
if (typeof str !== "string") {
throw new Error("必须是字符串");
}
this.string.push(str);
};
// 执行数组中字符串相连的操作
StringBuffer.prototype.toString = function () {
return this.string.join("");
};
StringBuffer._initialized = true;
}
}
console.time("str2");
let str2 = new StringBuffer();
for (let index = 0; index < count; index++) {
str2.append("str2 ");
}
let str2Result = str2.toString();
console.timeEnd("str2");
这样在上层使用的时候,就不会有阅读障碍了。
该内容是对学习过程的梳理,并非原创。原创来自ECMAScript 定义类或对象,如侵删。