วิธีที่มีประสิทธิภาพมากที่สุดในการต่อสตริงใน JavaScript?


163

ใน JavaScript ฉันมีลูปที่มีการวนซ้ำหลายครั้งและในการวนซ้ำแต่ละครั้งฉันกำลังสร้างสตริงขนาดใหญ่ที่มี+=โอเปอเรเตอร์จำนวนมาก มีวิธีที่มีประสิทธิภาพมากกว่าในการสร้างสตริงหรือไม่? ฉันกำลังคิดเกี่ยวกับการสร้างอาร์เรย์แบบไดนามิกที่ฉันเพิ่มสตริงลงไปแล้วทำการเข้าร่วม ใครสามารถอธิบายและยกตัวอย่างวิธีที่เร็วที่สุดในการทำสิ่งนี้?


2
คุณใช้สายอักขระทำอะไร เคล็ดลับประสิทธิภาพการทำงานใด ๆ นี้จะแตกต่างกันไปตามสภาพแวดล้อมของคุณขนาดของสายอักขระวิธีการที่เอ็นจิ้น js บางตัวปรับการทำงานต่าง ๆ ให้เหมาะสม ฯลฯ
Ben McCormick

1
อาจซ้ำซ้อนกับstackoverflow.com/questions/7299010/…
rab

5
ตรวจสอบลิงค์นี้jsperf.com/join-concat/2
rab

ฉันใช้ IE9 แต่อยู่ในโหมดความเข้ากันได้ของ IE8 (ซึ่งฉันไม่สามารถเปลี่ยนได้) สตริงขนาดใหญ่เป็นสิ่งที่ฉันจะแทรกลงใน DOM โดยใช้ jquery
โอเมก้า

ดูเพิ่มเติมการต่อข้อความสตริง JavaScript
Bergi

คำตอบ:


135

ดูเหมือนว่าอิงจากการวัดประสิทธิภาพของJSPerfที่ใช้+=เป็นวิธีที่เร็วที่สุด แต่ไม่จำเป็นว่าในทุกเบราว์เซอร์

สำหรับการสร้างสตริงใน DOM ดูเหมือนว่าจะเป็นการดีกว่าที่จะต่อสตริงเข้าด้วยกันก่อนแล้วจึงเพิ่มไปยัง DOM แทนที่จะเพิ่มซ้ำลงใน dom คุณควรเปรียบเทียบกรณีของคุณเอง

(ขอบคุณ @zAlbee สำหรับการแก้ไข)


1
ดูในหน้าที่เชื่อมโยง ดูเหมือนว่ามีความแตกต่างเล็กน้อยระหว่าง+=และทำการเข้าร่วมในอาร์เรย์
Jakub Hampl

ดูเหมือนว่าการเพิ่มลงใน DOM สำหรับทุกสายอักขระคือ66%(สำหรับ IE9) เร็วกว่าการสร้างสตริงออกจากนั้นจึงเพิ่มสตริงลงใน DOM
โอเมก้า

หน้าที่เชื่อมโยงนั้นใช้ + = สำหรับการทดสอบทั้งคู่ไม่มี. join () ต่อหน้าดังนั้นจึงเป็นการทดสอบที่ไม่มีความหมายซึ่งจะแสดงเพียงเสียงว่า "แตกต่าง" เท่านั้น ตัวอย่างที่ดีของ js ที่มีเสียงดังถึงแม้ว่า ... dom นั้นช้ากว่าสตริงดังนั้นควรใช้อย่างประหยัด
dandavis

เวลาเป็นเพียงองค์ประกอบเดียว สำหรับกิจวัตรซ้ำแล้วซ้ำอีกฉันสงสัยว่าผลกระทบต่อ GC คืออะไรระหว่างวิธีการต่างๆ
David Bradley

สำหรับสตริงขนาดใหญ่ array.join อาจจะดีกว่าเนื่องจากข้อผิดพลาดหน่วยความจำอันไม่พึงประสงค์ของสตริง concat ข้อผิดพลาดchromium.org/p/v8/issues/detail?id=3175
mwag

70

ฉันไม่มีความคิดเห็นเกี่ยวกับการต่อข้อมูลเอง แต่ฉันต้องการจะชี้ให้เห็นว่าคำแนะนำของ @Jakub Hampl:

สำหรับการสร้างสตริงใน DOM ในบางกรณีมันอาจเป็นการดีกว่าถ้าเพิ่มซ้ำใน DOM แต่ควรเพิ่มสตริงขนาดใหญ่ในครั้งเดียว

ผิดเพราะมันขึ้นอยู่กับการทดสอบที่มีข้อบกพร่อง การทดสอบนั้นไม่ได้ผนวกเข้ากับ DOM จริงๆ

การทดสอบนี้คงที่แสดงให้เห็นว่าการสร้างสตริงทั้งหมดในครั้งเดียวก่อนที่จะเรนเดอร์มันเร็วกว่ามาก มันไม่ใช่การแข่งขัน

(ขออภัยนี่เป็นคำตอบที่แยกจากกัน แต่ฉันยังไม่มีตัวแทนเพียงพอที่จะแสดงความคิดเห็นเกี่ยวกับคำตอบ)


4
ฉันคิดว่ามันคุ้มค่าที่จะเป็นคำตอบในตัวเองเพราะมันมีการทดสอบและข้อสรุป (แม้ว่าการทดสอบจะได้รับการดลใจจากคำตอบอื่นนั่นก็น่าจะใช้ได้) ไม่จำเป็นต้องขอโทษ
user202729

14

สามปีที่ผ่านมาตั้งแต่ตอบคำถามนี้ แต่ฉันจะตอบคำถามต่อไป :)

จริงๆแล้วคำตอบที่ยอมรับนั้นไม่ถูกต้อง การทดสอบของจาคุบใช้สตริงฮาร์ดโค้ดซึ่งช่วยให้เอ็นจิน JS สามารถประมวลผลโค้ดได้อย่างเหมาะสม (V8 ของ Google นั้นเก่งในเรื่องนี้จริงๆ!) แต่ทันทีที่คุณใช้สตริงสุ่มแบบสมบูรณ์ ( นี่คือ JSPerf ) การต่อสตริงจะอยู่ในตำแหน่งที่สอง


น่าสนใจด้วย Chrome 54 และ Firefox 45 บนเครื่อง Windows ของฉัน concat นั้นเร็วกว่าสองเท่าโดยใช้รุ่นของคุณ IE 11 นั้นช้ากว่าเบราว์เซอร์อีกสองตัวที่ไม่ได้ต่อกัน
ShawnFumo

4
มันแตกต่างจากรุ่นสู่รุ่น ฉันเดาว่าตอนนี้ VM ของ Chrome อาจมีการเพิ่มประสิทธิภาพล่วงหน้าสำหรับกรณีนี้ ฉันทดสอบอีกครั้งบน Chrome v53 และการต่อกันเป็นวิธีแก้ปัญหาที่เร็วที่สุด: D ฮาร์ดแวร์เดียวกัน แต่รุ่น Chrome ที่แตกต่างกันให้ผลลัพธ์ที่ต่างกันโดยสิ้นเชิง
Volodymyr Usarskyy

8

นอกจากนี้คุณยังสามารถทำ concat สตริงที่มีตัวอักษรของแม่แบบ ฉันได้อัปเดตการทดสอบ JSPerfของโปสเตอร์อื่น ๆเพื่อรวมไว้

for (var res = '', i = 0; i < data.length; i++) {
  res = `${res}${data[i]}`;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.