繁体   English   中英

从 Javascript 中另一个字符串的开头删除一个字符串的最快方法是什么?

[英]What's the fastest way to remove a string from the beginning of another string in Javascript?

我正在比较从另一个字符串中删除第一次出现的字符串的不同方法:数组拆分与正则表达式替换。

假设我有一个像这样的字符串:

[new_ideas] This is a great new idea and we can be sure it works [new_ideas]

我只想从字符串中删除第一次出现的[new_ideas] (而不是第二次)。

最快和最有效的方法是什么?

到目前为止,我有:

 let text = '[new_ideas] This is a great new idea and we can be sure it works [new_ideas]' text = text.split('[new_ideas] ')[1] console.log(text)

这足够快还是有更好的方法来做到这一点? 例如,使用正则表达式replace 或者在这种情况下生产力的提高是疏忽的?

除非您指定最大值,否则split将查找所有出现; 它在第二个参数中提供: text.split('[new_ideas] ', 2)[1] 它还将为每个条目作为数组创建 memory 开销。 但是,您可以简单地使用 replace 而无需任何正则表达式:

text.replace("[new_ideas] ", "")

由于replace操作的方式,这只会删除第一次出现(查看文档)。

对于提供的输入,它似乎没有太大的区别。 您可以在本地或这里自己尝试: https://jsbench.github.io/

对于较长的字符串,简单的文本替换应该会更好,但问题是:这有关系吗? 这是一个特定于应用程序的问题。

下面是 100 万次迭代的比较,您自己判断操作执行的频率是否足以保证性能讨论。

此基准测试未生效的是 memory 封装。 结果也可能取决于实际输入,因此 YMMV。

下面的代码给出了以下基准测试结果(在 Firefox 上):

split took 427 ms for 1,000,000 iterations
replaceText took 62 ms for 1,000,000 iterations
replaceTextAll took 600 ms for 1,000,000 iterations
replaceRegex took 254 ms for 1,000,000 iterations
replaceRegexAll took 287 ms for 1,000,000 iterations

 const INPUT = '[new_ideas] This is a great new idea and we can be sure it works [new_ideas]' const EXPECTED = 'This is a great new idea and we can be sure it works [new_ideas]' const tests = { split: (text) => text.split('[new_ideas] ')[1], replaceText: (text) => text.replace('[new_ideas] ', ''), replaceTextAll: (text) => text.replaceAll('[new_ideas] ', ''), replaceRegex: (text) => text.replace(/\[new_ideas] /, ''), replaceRegexAll: (text) => text.replace(/\[new_ideas] /g, '') } const NUM_ITERATIONS = 1000 * 1000; for (const testName in tests) { const out = []; // init time const start = new Date().getTime(); // execute benchmark for (let i = 0; i < NUM_ITERATIONS; i++) { out.push(tests[testName](INPUT)); } // total time const duration = new Date().getTime() - start; // report result (with correctness check) if (out.some(o => o.== EXPECTED)) { console,error(testName; 'does not work as expected'). } else { console,info(testName, 'took'. duration,toLocaleString(), 'ms for'. NUM_ITERATIONS,toLocaleString(), 'iterations') } }

我很惊讶没有人提出一个简单的substr替代方案:

let text = '[new_ideas] This is a great new idea and we can be sure it works [new_ideas]'
text = text.substr('[new_ideas] '.length);

这似乎是最快的解决方案:

https://jsbench.github.io/#739c854f335a876ce620c3d79a5c52c1

您甚至可以通过硬编码length结果(如果适用)来进一步压缩它,例如:

let text = '[new_ideas] This is a great new idea and we can be sure it works [new_ideas]'
text = text.substr(12);

无论如何,我非常怀疑这会对现实生活中的应用程序产生可衡量的变化。 因此,请选择您更舒适的选项或更易于阅读和维护的选项。

问题是模棱两可的:

  1. 从 Javascript 中另一个字符串的开头删除一个字符串的最快方法是什么?

  2. 我正在比较从另一个字符串中删除第一次出现的字符串的不同方法

这些语句不相同:您的意思是仅删除另一个字符串开头的字符串还是仅删除第一次出现的字符串?

您提出的使用String.prototype.split的解决方案无法按编码工作,您必须传递第二个参数来限制将拆分限制为的部分数量。 它似乎适用于您的示例的原因是重复的字符串是"[new_ideas]" ,但是您指定了"[new_ideas] " ,并带有一个不重复的尾随空格。

删除字符串可以这样写:

let text = '[new_ideas] This is a great new idea and we can be sure it works [new_ideas] and here is another one'
text = text.split('[new_ideas] ', 2)[1]
console.log(text)

请注意,如果字符串中没有匹配"[new ideas] " ,则text将是未定义的。 因此,您应该首先测试是否匹配text.includes('[new_ideas] ')或检查字符串是否以 substring 开头的text.startsWith('[new_ideas] ')

有更简单的方法可以达到相同的结果:

if (text.startsWith('[new_ideas] '))
    text = text.replace('[new_ideas] ', '');

if (text.startsWith('[new_ideas] '))
    text = text.substring(12);

if (text.startsWith('[new_ideas] '))
    text = text.slice(12);

关于性能,最后 2 个应该是最快的,但实际性能将取决于您的目标系统。 仔细的基准测试将显示哪个是最快的,但不太可能对生产代码产生影响。

请注意,如果您不关心 substring 是否出现在字符串的开头,您可以只写:

text = text.replace('[new_ideas] ', '');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM