ทางออกที่เร็วที่สุด?
ฉันใช้การวัดประสิทธิภาพและวิธีแก้ปัญหานี้ชนะอย่างมหาศาล: 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
ได้รับผลกระทบอย่างมากและมีขนาดประมาณ 2 คำสั่งที่ช้าลง การใช้join
กับผลลัพธ์ของsplit
หลักสูตรเพิ่มการลงโทษประสิทธิภาพเพิ่มเติม
ทำไมพวกเขาถึงช้าลง เมื่อใดก็ตามที่วัตถุหรืออาร์เรย์ใหม่จะต้องมีการสร้าง JS ต้องขอหน่วยความจำจากระบบปฏิบัติการ กระบวนการนี้ช้ามาก
ต่อไปนี้เป็นแนวทางทั่วไปบางประการในกรณีที่คุณกำลังไล่ตามมาตรฐาน:
- การจัดสรรหน่วยความจำแบบไดนามิกใหม่สำหรับวัตถุ
{}
หรืออาร์เรย์[]
(เช่นเดียวกับที่split
สร้าง) จะมีค่าใช้จ่ายจำนวนมากในประสิทธิภาพ
RegExp
การค้นหามีความซับซ้อนและช้ากว่าการค้นหาสตริง
- หากคุณมีอาร์เรย์อยู่แล้วการทำลายอาร์เรย์จะเร็วพอ ๆ กับการทำดัชนีอย่างชัดเจนและดูดีมาก
การลบที่นอกเหนือจากอินสแตนซ์แรก
ต่อไปนี้เป็นโซลูชันที่จะแบ่งส่วนและรวมอินสแตนซ์ที่ n มันไม่เร็วนัก แต่สำหรับคำถามของ OP gobble(element, '_', 1)
นั้นยังคงเร็วกว่า 2x RegExp
หรือมากกว่าและมีsplit
วิธีแก้ไขมากกว่า:
/*
`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)
จะลบคำนำหน้าเหมือนคำตอบแรกในคำตอบนี้
- การทดสอบรันใน Chrome 70.0.3538.110 บน macOSX 10.14