如何在Javascript中有效地操作字符串



如何在每次更改时都不创建新字符串的情况下有效地更改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来获取要存储的值

最新更新