最速のソリューション?
私はいくつかのベンチマークを実行しましたが、このソリューションは大成功しました:1
str.slice(str.indexOf(delim) + delim.length)
// as function
function gobbleStart(str, delim) {
return str.slice(str.indexOf(delim) + delim.length);
}
// as polyfill
String.prototype.gobbleStart = function(delim) {
return this.slice(this.indexOf(delim) + delim.length);
};
他のソリューションとのパフォーマンス比較
substr
代わりにを使用することを除いて、唯一の近い候補は同じコード行でしたslice
。
私は関与しようとした他のソリューションsplit
またはRegExp
sが大きなパフォーマンスヒットを取り、2程度だった桁違いに遅いです。もちろん、のjoin
結果を使用すると、split
パフォーマンスがさらに低下します。
なぜ遅いのですか?新しいオブジェクトまたは配列を作成する必要があるときはいつでも、JSはOSからメモリのチャンクを要求する必要があります。このプロセスは非常に遅いです。
ベンチマークを追跡する場合の一般的なガイドラインを次に示します。
- オブジェクト
{}
または配列[]
(split
作成するものなど)の新しい動的メモリ割り当ては、パフォーマンスに多くのコストがかかります。
RegExp
検索はより複雑であるため、文字列検索よりも時間がかかります。
- すでに配列がある場合、配列の分解は明示的に配列にインデックスを付けるのと同じくらい速く、見栄えが良いです。
最初のインスタンスを超えて削除
以下は、n番目のインスタンスまでスライスするソリューションです。それほど速くはありませんが、OPの質問でgobble(element, '_', 1)
は、RegExp
またはsplit
ソリューションよりも2倍以上高速であり、さらに多くのことができます。
/*
`gobble`, given a positive, non-zero `limit`, deletes
characters from the beginning of `haystack` until `needle` has
been encountered and deleted `limit` times or no more instances
of `needle` exist; then it returns what remains. If `limit` is
zero or negative, delete from the beginning only until `-(limit)`
occurrences or less of `needle` remain.
*/
function gobble(haystack, needle, limit = 0) {
let remain = limit;
if (limit <= 0) { // set remain to count of delim - num to leave
let i = 0;
while (i < haystack.length) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain++;
i = found + needle.length;
}
}
let i = 0;
while (remain > 0) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain--;
i = found + needle.length;
}
return haystack.slice(i);
}
上記の定義でgobble('path/to/file.txt', '/')
は、ファイルの名前を指定し、gobble('prefix_category_item', '_', 1)
この回答の最初のソリューションのように接頭辞を削除します。
- テストは、macOSX 10.14上のChrome 70.0.3538.110で実行されました。