如何在每次更改时都不创建新字符串的情况下有效地更改Javascript中的字符串?所附代码将其说明为每个";结果+=";活动将生成一个新字符串。
使用Unit8Array作为工作区域的想法似乎失败了,因为转换为字符串的效率同样低。
; Use mask to change characters in string to a
; '-' if mask dictates that.
function maskOutput(input, mask) {
let result = '';
for (let i=0; i < input.length; i++){
if (mask.charAt(i) === 'X') {
result += '-';
} else {
result += input.charAt(i);
}
}
return result;
}
我要做的第一件事是检查临时字符串是否真的给我的页面/应用程序带来了问题,因为JavaScript引擎非常擅长优化常见问题,比如很多临时字符串,特别是在像maskOutput
这样字符串是串接结果的情况下。(Chrome和其他地方的引擎V8在必要时通过将部分字符串组合到链表中来实现这一点。(maskOutput
函数中的字符串串联似乎不太可能成为页面/应用程序的瓶颈。过去,你会看到代码通过使用数组,然后在最后使用.join("")
来构建一个大字符串,这是一种相当标准的做法,因为大约在2009年速度更快,但从那时起,JavaScript引擎已经在上进行了大量,我记得几年前只在字符串上使用+=
变得更快了。
如果在某些用例(内存压力,不管怎样(中,临时字符串是一个问题,您可以使用单个字符的纯数组,如果需要,可以在开始时转换一次(从字符串到数组((在您的情况下不是这样(,并在结束时(从数组到字符串(转换一次。但对于像我想象的maskOutput
句柄这样的短字符串,正如你所说,开销是不值得的
但只是为了完整性:
function maskOutput(input, mask) {
const len = input.length;
let result = Array(len); // Some engines actually do optimize this
for (let i = 0; i < len; i++) {
if (mask[i] === 'X') { // No need for a method call
result[i] = "-";
} else {
result[i] = input[i];
}
}
return result.join("");
}
ccoUint8Array
将是一个糟糕的选择,因为:
- 字符串由16位值组成(UTF-16代码单元(。如果要使用类型化数组,
Uint16Array
会更合适 - 将一个值放入
Uint8Array
/Uint16Array
需要将其从JavaScript的数字类型转换为8位/16位无符号整数(读取时反之亦然(,这非常便宜,但不是免费的。大概您必须使用charCodeAt
来获取要存储的值