簡體   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