提问人:user7858768 提问时间:9/21/2021 更新时间:9/21/2021 访问量:144
Javascript:为什么字符串相等对于较长的字符串需要更长的时间?
Javascript: Why does equality of strings take longer for longer strings?
问:
在下面的代码中,将创建长度相等的 1Mil 字符串。 然后,它们被循环以查找匹配的字符串。 第一次运行的字符串长度是第二次运行的 3 倍。
预期的结果是,对不同长度的字符串进行相等比较所需的时间不会因“字符串实习”而改变。但是,结果显示,长度为 3 倍的字符串大约需要 3 次才能进行相等性检查。为什么?
import { v4 as uuidv4 } from 'uuid';
export const uuid = () => {
return uuidv4();
};
function createSingleId(howManyUuidsInOneId1: number) {
let id = '';
for (let j = 0; j < howManyUuidsInOneId1; j++) {
id += uuid();
}
return id;
}
function generate(howManyIds: number, howManyUuidsInOneId: number) {
const ids = [];
for (let i = 0; i < howManyIds; i++) {
ids.push(createSingleId(howManyUuidsInOneId));
}
return ids;
}
const main = (howManyIds: number, howManyUuidsInOneId:number) => {
const ids = generate(howManyIds, howManyUuidsInOneId);
const toFind = createSingleId(howManyUuidsInOneId);
console.log(`Sample id being compared: '${toFind}'`);
const before = new Date().getTime();
ids.filter(id => id === toFind);
console.log(`Took '${new Date().getTime() - before}ms' to loop through and equal compare '${howManyIds}' when stacked '${howManyUuidsInOneId}' in single id`);
};
main(1000000, 3);
main(1000000, 1);
输出:
Sample id being compared: 'dc03bf00-6f2a-48d9-b3ca-b6ac45782c5cefaa92c0-9372-4f47-bcec-f9fbb41d4625e0c5c278-b574-4a9f-a77e-110cbc6bf601'
Took '64ms' to loop through and equal compare '1000000' when stacked '3' in single id
Sample id being compared: '07e693ce-49a1-4cc6-90e1-0bd99629123b'
Took '19ms' to loop through and equal compare '1000000' when stacked '1' in single id
> node --version
v15.14.0
答:
4赞
Bergi
9/21/2021
#1
预期的结果是,对不同长度的字符串进行相等比较所需的时间不会因“字符串实习”而改变。
不,字符串实习仅意味着对于某些字符串,您知道它们是相同的,因为它们存储在相同的位置,例如,对于从相同字符串文字创建的字符串值。但并不是所有的字符串(尤其是不是动态创建的字符串)都会被隔离,并且具有不同的内存地址并不能说明字符串的内容。如果内存位置检查失败,您仍然需要像往常一样比较字符串内容。
一些例子来证明这一点:
function generateString(len) {
let x = "";
for (let i=0; i<len; i++) x+= String.fromCharCode(64+i%64);
return x;
}
function time(callback, desc) {
const before = performance.now();
const res = callback();
console.log(`Took ${performance.now()-before}ms to ${desc}`);
return res;
}
const strLen = 5000000;
const a = generateString(strLen);
const b = generateString(strLen);
console.assert(a === b);
const str = a;
time(() => str === a, 'compare a with itself');
time(() => str === b, 'compare a with b');
a
并且具有相同的内容,但(在内存中)是不同的字符串对象,因为它们是在不同的调用中累积的。 引用与这样做相同的值。b
generateString
str
a
评论
0赞
user7858768
9/21/2021
说得很有道理。出于某种原因,我认为所有字符串都是动态的。
评论