การเขียนโค้ด Javascript ที่มีประสิทธิภาพสูงโดยไม่ทำให้เสียเวลา


10

เมื่อเขียนโค้ดที่ไวต่อประสิทธิภาพใน Javascript ซึ่งทำงานในอาร์เรย์ตัวเลขขนาดใหญ่ (คิดว่าเป็นแพคเกจพีชคณิตเชิงเส้นการทำงานกับจำนวนเต็มหรือตัวเลขทศนิยม) หนึ่งต้องการให้ JIT ช่วยเท่าที่จะทำได้ ประมาณนี้หมายถึง:

  1. เราต้องการให้อาร์เรย์ของเราบรรจุ SMIs (จำนวนเต็มเล็กน้อย) หรือบรรจุคู่ขึ้นอยู่กับว่าเราทำการคำนวณจำนวนเต็มหรือทศนิยม
  2. เราต้องการที่จะส่งสิ่งประเภทเดียวกันไปยังฟังก์ชั่นเสมอเพื่อที่พวกเขาจะไม่ได้รับป้ายกำกับ "megamorphic" และ deoptimised ตัวอย่างเช่นเราต้องการที่จะโทรหาvec.add(x, y)ทั้งคู่xและyเป็นอาร์เรย์ SMI ที่บรรจุอยู่หรือทั้งสองอาร์เรย์ที่บรรจุแล้ว
  3. เราต้องการให้ฟังก์ชั่นอินไลน์มากที่สุด

เมื่อมีหนึ่งเร่ร่อนอยู่นอกกรณีเหล่านี้จะมีการลดลงของประสิทธิภาพการทำงานอย่างกะทันหันและรุนแรง สิ่งนี้สามารถเกิดขึ้นได้ด้วยเหตุผลที่ไม่น่ากลัวหลายประการ:

  1. คุณอาจเปิด SMI myArray.map(x => -x)อาร์เรย์บรรจุลงในบรรจุอาร์เรย์คู่ผ่านการดำเนินการที่ดูเหมือนไม่มีอันตรายเช่นเทียบเท่า นี่เป็นกรณีที่แย่ที่สุด "ดีที่สุด" เนื่องจากอาร์เรย์ Double ที่บรรจุอยู่นั้นยังคงเร็วมาก
  2. คุณอาจจะกลายอาร์เรย์ที่บรรจุลงในกล่องอาร์เรย์ทั่วไปตัวอย่างเช่นโดยการทำแผนที่อาร์เรย์มากกว่าฟังก์ชั่นที่ (โดยไม่คาดคิด) กลับหรือnull undefinedกรณีที่ไม่ดีนี้ค่อนข้างง่ายที่จะหลีกเลี่ยง
  3. คุณอาจ deoptimise ฟังก์ชั่นทั้งหมดเช่นvec.add()โดยผ่านสิ่งต่าง ๆ มากเกินไปและเปลี่ยนเป็น megamorphic สิ่งนี้อาจเกิดขึ้นได้หากคุณต้องการทำ "การเขียนโปรแกรมทั่วไป" ซึ่งvec.add()จะใช้ทั้งในกรณีที่คุณไม่ได้ระมัดระวังเกี่ยวกับประเภท (ดังนั้นจึงเห็นหลายประเภทเข้ามา) และในกรณีที่คุณต้องการประสิทธิภาพสูงสุด (มันควรจะได้รับคู่ผสมชนิดบรรจุกล่องเท่านั้น)

คำถามของฉันเป็นคำถามที่อ่อนกว่าเกี่ยวกับวิธีการเขียนโค้ด Javascript ที่มีประสิทธิภาพสูงโดยคำนึงถึงข้อพิจารณาข้างต้นในขณะที่ยังคงรักษาโค้ดที่ดีและอ่านได้ คำถามย่อยเฉพาะบางคำถามเพื่อให้คุณทราบว่าฉันต้องการคำตอบประเภทใด:

  • มีชุดแนวทางในการเขียนโปรแกรมในขณะที่อยู่ในโลกของอาร์เรย์ SMI ที่บรรจุ (ตัวอย่าง) หรือไม่?
  • เป็นไปได้ที่จะทำการเขียนโปรแกรมทั่วไปที่มีประสิทธิภาพสูงใน Javascript โดยไม่ใช้สิ่งใดสิ่งหนึ่งเช่นระบบมาโครเพื่อแทรกสิ่งต่างๆvec.add()ลงใน callsites?
  • รหัสประสิทธิภาพสูงแบบแยกส่วนได้กลายเป็น libaries ในแง่ของสิ่งต่าง ๆ เช่นไซต์โทร megamorphic และ deoptimisations ได้อย่างไร ตัวอย่างเช่นถ้าฉันมีความสุขกับการใช้แพ็คเกจพีชคณิตเชิงเส้นAด้วยความเร็วสูงและจากนั้นฉันนำเข้าแพคเกจBที่ขึ้นอยู่กับAแต่Bเรียกมันด้วยประเภทอื่น ๆ และ deoptimises มันทันใดนั้น (โดยไม่ต้องเปลี่ยนรหัสของฉัน) รหัสของฉันทำงานช้าลง
  • มีเครื่องมือวัดที่ใช้งานง่ายสำหรับตรวจสอบสิ่งที่เอ็นจิน Javascript ทำงานภายในกับชนิดหรือไม่?

1
นั่นเป็นหัวข้อที่น่าสนใจมากและโพสต์ที่เขียนได้ดีมากซึ่งแสดงว่าคุณได้ทำวิจัยอย่างถูกต้องแล้ว อย่างไรก็ตามฉันกลัวว่าคำถามนั้นกว้างเกินไปสำหรับรูปแบบ SO และมันจะดึงดูดความคิดเห็นมากกว่าข้อเท็จจริงอย่างหลีกเลี่ยงไม่ได้ การปรับให้เหมาะสมของรหัสเป็นเรื่องที่ซับซ้อนมากและเอ็นจิ้นสองเวอร์ชันอาจไม่ทำงานเหมือนกัน ฉันคิดว่ามีหนึ่งในผู้รับผิดชอบ V8 JIT ที่แขวนอยู่รอบ ๆ ดังนั้นบางทีพวกเขาอาจให้คำตอบที่ถูกต้องสำหรับเครื่องยนต์ของพวกเขา แต่สำหรับพวกเขาฉันคิดว่ามันจะกว้างเกินไปสำหรับเรื่อง Q / A เดียว .
Kaiido

"คำถามของฉันเป็นคำถามที่อ่อนนุ่มกว่าเกี่ยวกับวิธีการเขียนโค้ดจาวาสคริปต์ที่มีประสิทธิภาพสูง ... " โปรดทราบว่าจาวาสคริปต์ให้การวางไข่ของกระบวนการพื้นหลัง (ผู้ปฏิบัติงานเว็บ) และยังมีห้องสมุดที่เข้ามา การเสนอ GPU (tensorflow.js และ gpu.js) นอกเหนือจากการรวบรวมเพื่อเพิ่มปริมาณการคำนวณของแอพพลิเคชั่นที่ใช้จาวาสคริปต์ ...
Jon Trent

@ JonTrent ที่จริงฉันโกหกเล็ก ๆ น้อย ๆ ในโพสต์ของฉันฉันไม่สนใจมากสำหรับพีชคณิตเชิงเส้นแอปพลิเคชันคลาสสิก แต่สำหรับพีชคณิตคอมพิวเตอร์มากกว่าจำนวนเต็ม ซึ่งหมายความว่าแพ็กเกจตัวเลขที่มีอยู่จำนวนมากจะถูกตัดออกทันทีเนื่องจาก (ตัวอย่าง) ในขณะที่เมทริกซ์การลดแถวจะแบ่งเป็น 2 ซึ่งเป็น "ไม่อนุญาต" ในโลกที่ฉันทำงานมาตั้งแต่ (1/2) ไม่ใช่จำนวนเต็ม ฉันได้พิจารณาผู้ทำงานเว็บ (โดยเฉพาะอย่างยิ่งสำหรับการคำนวณระยะยาวที่ฉันต้องการยกเลิก) แต่ปัญหาที่ฉันพูดถึงที่นี่คือการลดเวลาในการตอบสนองต่อการโต้ตอบที่ลดลง
Joppy

สำหรับเลขคณิตเลขจำนวนเต็มใน JavaScript คุณอาจกำลังดูโค้ดสไตล์ asm.js โดยคร่าว ๆ ว่า "หยุด|0การทำงานทุกครั้ง" มันไม่สวย แต่สิ่งที่ดีที่สุดที่คุณสามารถทำได้ในภาษาที่ไม่มีจำนวนเต็มเหมาะสม คุณสามารถใช้ BigInts ได้ แต่ ณ วันนี้มันไม่ได้เร็วมากในเครื่องมือทั่วไป (ส่วนใหญ่เกิดจากการขาดความต้องการ)
jmrk

คำตอบ:


8

นักพัฒนา V8 ที่นี่ ด้วยจำนวนความสนใจในคำถามนี้และการขาดคำตอบอื่น ๆ ฉันสามารถให้ภาพนี้ได้ ฉันกลัวว่ามันจะไม่ใช่คำตอบที่คุณหวังไว้

มีชุดแนวทางในการเขียนโปรแกรมในขณะที่อยู่ในโลกของอาร์เรย์ SMI ที่บรรจุ (ตัวอย่าง) หรือไม่?

คำตอบสั้น ๆ : มันอยู่ที่นี่: const guidelines = ["keep your integers small enough"].

คำตอบอีกต่อไป: การให้แนวทางที่ครอบคลุมนั้นเป็นเรื่องยากด้วยเหตุผลหลายประการ โดยทั่วไปแล้วความคิดเห็นของเราคือผู้พัฒนา JavaScript ควรเขียนโค้ดที่เหมาะสมกับพวกเขาและกรณีการใช้งานและนักพัฒนาเครื่องมือ JavaScript ควรรู้วิธีเรียกใช้โค้ดนั้นอย่างรวดเร็วในเอ็นจิ้นของพวกเขา ในทางกลับกันมีข้อ จำกัด บางประการสำหรับอุดมคตินั้นในแง่ที่ว่ารูปแบบการเข้ารหัสบางอย่างจะมีค่าใช้จ่ายประสิทธิภาพสูงกว่าคนอื่นเสมอโดยไม่คำนึงถึงตัวเลือกการใช้งานเครื่องยนต์และความพยายามเพิ่มประสิทธิภาพ

เมื่อเราพูดถึงคำแนะนำเกี่ยวกับประสิทธิภาพเราพยายามระลึกไว้เสมอและประเมินอย่างรอบคอบว่าคำแนะนำใดมีโอกาสสูงที่จะใช้งานได้กับเครื่องยนต์จำนวนมากและเป็นเวลาหลายปีและยังมีนิสัยสำนึกผิด / ไม่ล่วงล้ำ

กลับไปที่ตัวอย่างในมือ: การใช้ Smis ภายในควรจะเป็นรายละเอียดการใช้งานที่รหัสผู้ใช้ไม่จำเป็นต้องรู้ มันจะทำให้บางกรณีมีประสิทธิภาพมากขึ้นและไม่ควรเจ็บในกรณีอื่น มีบางเครื่องมือที่ใช้ Smis (ตัวอย่างเช่น AFAIK Firefox / Spidermonkey ที่ผ่านมาไม่ได้; ฉันได้ยินมาว่าในบางกรณีพวกเขาใช้ Smis ในทุกวันนี้ แต่ฉันไม่ทราบรายละเอียดใด ๆ เรื่อง) ใน V8 ขนาดของ Smis เป็นรายละเอียดภายในและมีการเปลี่ยนแปลงตามเวลาและรุ่นจริง ๆ บนแพลตฟอร์ม 32 บิตซึ่งเคยเป็นกรณีใช้งานส่วนใหญ่ Smis เป็นจำนวนเต็ม 31 บิตที่ลงนามแล้วเสมอ บนแพลตฟอร์ม 64 บิตที่พวกเขาเคยเป็นจำนวนเต็ม 32 บิตซึ่งดูเหมือนว่าจะเป็นกรณีที่พบบ่อยที่สุดจนกระทั่งใน Chrome 80 เราได้ส่ง สำหรับสถาปัตยกรรม 64- บิตซึ่งจำเป็นต้องลดขนาด Smi ให้เหลือ 31 บิตซึ่งเป็นที่รู้จักจากแพลตฟอร์ม 32 บิต หากคุณบังเอิญมีการใช้งานตามข้อสันนิษฐานว่าโดยทั่วไปแล้ว Smis เป็น 32 บิตคุณจะได้รับสถานการณ์ที่โชคร้ายเช่นนี้นี้

โชคดีที่คุณจดบันทึกไว้อาร์เรย์สองตัวยังคงเร็วมาก สำหรับโค้ดที่เป็นตัวเลขหนักอาจเป็นไปได้ที่จะสมมติ / กำหนดเป้าหมายอาร์เรย์คู่ เมื่อพิจารณาจากความชุกของ doubles ใน JavaScript จึงมีเหตุผลที่จะสมมติว่าเอ็นจิ้นทั้งหมดมีการสนับสนุนที่ดีสำหรับ doubles และ double array

เป็นไปได้ที่จะทำการเขียนโปรแกรมทั่วไปที่มีประสิทธิภาพสูงใน Javascript โดยไม่ต้องใช้อะไรเช่นระบบมาโครในการอินไลน์สิ่งต่าง ๆ เช่น vec.add () ลงใน callsites?

"ทั่วไป" มักจะขัดแย้งกับ "ประสิทธิภาพสูง" สิ่งนี้ไม่เกี่ยวข้องกับ JavaScript หรือการปรับใช้เครื่องมือเฉพาะ

รหัส "ทั่วไป" หมายความว่าต้องทำการตัดสินใจในขณะใช้งานจริง ทุกครั้งที่คุณเรียกใช้ฟังก์ชันรหัสต้องเรียกใช้เพื่อระบุว่า "เป็นxจำนวนเต็มหรือไม่ถ้าเป็นเช่นนั้นให้พา ธ โค้ดนั้นxเป็นสตริงหรือไม่แล้วข้ามไปที่นี่มันเป็นวัตถุหรือไม่.valueOfไม่มีหรือไม่จากนั้น อาจเป็นไปได้ว่า.toString()อาจใช้โซ่ต้นแบบของมันเรียกมันและเริ่มใหม่ตั้งแต่ต้นด้วยผลลัพธ์ " รหัสที่ได้รับการปรับปรุงประสิทธิภาพ "ประสิทธิภาพสูง" นั้นสร้างขึ้นจากแนวคิดที่จะลดการตรวจสอบแบบไดนามิกทั้งหมด เป็นไปได้ก็ต่อเมื่อเอ็นจิ้น / คอมไพเลอร์มีวิธีอนุมานชนิดล่วงหน้า: หากสามารถพิสูจน์ (หรือสมมติว่ามีความน่าจะxเป็นสูงพอ) ที่จะเป็นจำนวนเต็มเสมอมันจะต้องสร้างรหัสสำหรับกรณีนั้นเท่านั้น ( เตรียมพร้อมโดยการตรวจสอบประเภทหากข้อสันนิษฐานที่ไม่ได้มีส่วนเกี่ยวข้อง)

การฝังเป็นมุมฉากทั้งหมดนี้ ฟังก์ชั่น "ทั่วไป" ยังสามารถรับการ inline ในบางกรณีคอมไพเลอร์อาจเผยแพร่ข้อมูลชนิดลงในฟังก์ชัน inlined เพื่อลดความหลากหลายที่มี

(สำหรับการเปรียบเทียบ: C ++ เป็นภาษาที่รวบรวมแบบสแตติกมีเทมเพลตเพื่อแก้ไขปัญหาที่เกี่ยวข้องในระยะสั้นพวกเขาปล่อยให้โปรแกรมเมอร์สั่งให้คอมไพเลอร์สร้างสำเนาเฉพาะของฟังก์ชัน (หรือคลาสทั้งหมด) โดยเฉพาะอย่างยิ่ง วิธีแก้ปัญหาที่ดีสำหรับบางกรณี แต่ไม่ใช่หากไม่มีชุดข้อเสียของตัวเองเช่นเวลาในการรวบรวมที่ยาวนานและไบนารีขนาดใหญ่แน่นอนว่า JavaScript ไม่มีเทมเพลตเช่นนี้คุณสามารถใช้evalเพื่อสร้างระบบที่ค่อนข้างคล้ายกัน ทำงานในข้อเสียที่คล้ายกัน: คุณจะต้องทำงานเทียบเท่ากับคอมไพเลอร์ของ C ++ ที่รันไทม์และคุณต้องกังวลเกี่ยวกับจำนวนโค้ดที่คุณสร้างขึ้น)

รหัสประสิทธิภาพสูงแบบแยกส่วนได้กลายเป็น libaries ในแง่ของสิ่งต่าง ๆ เช่นไซต์โทร megamorphic และ deoptimisations ได้อย่างไร ตัวอย่างเช่นถ้าฉันมีความสุขที่ใช้แพ็คเกจพีชคณิตเชิงเส้น A ที่ความเร็วสูงและจากนั้นฉันนำเข้าแพ็คเกจ B ที่ขึ้นอยู่กับ A แต่ B เรียกมันด้วยประเภทอื่น ๆ และ deoptimises มันในทันใด (โดยไม่ต้องเปลี่ยนรหัสของฉัน) รหัสของฉันทำงานช้า .

ใช่นั่นเป็นปัญหาทั่วไปของ JavaScript V8 เคยใช้ builtins บางอย่าง (คล้าย ๆArray.sort) ใน JavaScript ภายในและปัญหานี้ (ที่เราเรียกว่า "ความคิดเห็นเกี่ยวกับการตอบรับพิมพ์") เป็นหนึ่งในสาเหตุหลักที่ทำไมเราจึงย้ายออกจากเทคนิคนั้นโดยสิ้นเชิง

ที่กล่าวว่าสำหรับรหัสตัวเลขนั้นมีไม่กี่ประเภท (เฉพาะ Smis และ double) และตามที่คุณตั้งข้อสังเกตว่าพวกเขาควรจะมีประสิทธิภาพที่คล้ายกันในทางปฏิบัติดังนั้นในขณะที่มลพิษจากข้อเสนอแนะนั้นเป็นข้อกังวลทางทฤษฎีและในบางกรณี มีผลกระทบอย่างมีนัยสำคัญและเป็นไปได้อย่างมากว่าในสถานการณ์พีชคณิตเชิงเส้นคุณจะไม่เห็นความแตกต่างที่วัดได้

นอกจากนี้ภายในเครื่องยนต์ยังมีสถานการณ์อีกมากมายที่นอกเหนือจาก "หนึ่งประเภท == เร็ว" และ "มากกว่าหนึ่งประเภท == ช้า" หากการดำเนินการที่กำหนดได้เห็นทั้ง Smis และ doubles แล้วนั่นถือว่าใช้ได้ทั้งหมด การโหลดองค์ประกอบจากอาร์เรย์สองชนิดนั้นก็ดีเช่นกัน เราใช้คำว่า "megamorphic" สำหรับสถานการณ์เมื่อการโหลดได้เห็นประเภทที่แตกต่างกันมากมายที่มีให้ในการติดตามพวกเขาทีละรายการและใช้กลไกทั่วไปมากกว่าที่ปรับขนาดได้ดีกว่าประเภทจำนวนมาก - ฟังก์ชันที่มีโหลดดังกล่าวสามารถ ยังคงได้รับการเพิ่มประสิทธิภาพ "deoptimization" เป็นการกระทำที่เฉพาะเจาะจงในการทิ้งโค้ดที่ปรับให้เหมาะสมที่สุดสำหรับฟังก์ชั่นเพราะรูปแบบใหม่จะเห็นว่ายังไม่เคยเห็นมาก่อนและดังนั้นรหัสที่ปรับให้เหมาะสมจึงไม่พร้อมที่จะจัดการ แต่ถึงกระนั้นก็ดี เพียงกลับไปที่รหัสที่ไม่ได้เพิ่มประสิทธิภาพเพื่อรวบรวมคำติชมที่พิมพ์มากขึ้นและเพิ่มประสิทธิภาพอีกครั้งในภายหลัง หากเกิดขึ้นสองสามครั้งก็ไม่มีอะไรต้องกังวล มันจะกลายเป็นปัญหาในกรณีที่ไม่ดีทางพยาธิวิทยา

ดังนั้นบทสรุปของทั้งหมดที่คือไม่ต้องกังวลเกี่ยวกับเรื่องนี้ เพียงแค่เขียนรหัสที่สมเหตุสมผลให้เอ็นจิ้นจัดการกับมัน และโดย "สมเหตุสมผล" ฉันหมายถึง: สิ่งที่เหมาะสมสำหรับกรณีการใช้งานของคุณคือสามารถอ่านได้บำรุงรักษาใช้อัลกอริธึมที่มีประสิทธิภาพไม่มีข้อบกพร่องเช่นการอ่านเกินความยาวของอาร์เรย์ เป็นการดีที่นั่นคือทั้งหมดที่มีให้และคุณไม่จำเป็นต้องทำอะไรอีก ถ้ามันทำให้คุณรู้สึกดีขึ้นที่จะทำอะไรบางอย่างและ / หรือถ้าคุณสังเกตปัญหาการปฏิบัติจริง ๆ ฉันสามารถเสนอแนวคิดสองอย่าง:

การใช้ TypeScript สามารถช่วยได้ คำเตือนไขมันใหญ่: ประเภทของ TypeScript นั้นมุ่งเน้นไปที่ประสิทธิภาพของนักพัฒนาไม่ใช่ประสิทธิภาพการดำเนินการ (และเมื่อปรากฎออกมามุมมองทั้งสองนั้นมีความต้องการที่แตกต่างกันมากจากระบบประเภท) ที่กล่าวว่ามีบางส่วนที่ทับซ้อนกัน: เช่นถ้าคุณใส่คำอธิบายประกอบอย่างสม่ำเสมอเช่นnumberนั้นคอมไพเลอร์ TS จะเตือนคุณถ้าคุณตั้งใจใส่nullอาเรย์หรือฟังก์ชั่นที่ควรจะมี / ทำงานกับตัวเลขเท่านั้น แน่นอนว่าจำเป็นต้องมีการลงโทษทางวินัย: number_func(random_object as number)ช่องหนีเดี่ยวสามารถทำลายทุกอย่างได้อย่างเงียบ ๆ เพราะความถูกต้องของคำอธิบายประกอบประเภทไม่ได้บังคับใช้ที่ใดก็ได้

การใช้ TypedArrays สามารถช่วยได้เช่นกัน พวกเขามีค่าใช้จ่ายเพิ่มเติมเล็กน้อย (ปริมาณการใช้หน่วยความจำและความเร็วในการจัดสรร) ต่ออาร์เรย์เมื่อเทียบกับอาร์เรย์ JavaScript ปกติ (ดังนั้นหากคุณต้องการอาร์เรย์ขนาดเล็กจำนวนมากดังนั้นอาร์เรย์ปกติอาจมีประสิทธิภาพมากกว่า) และยืดหยุ่นน้อยกว่าเพราะไม่สามารถเติบโตได้ หรือลดขนาดหลังจากการจัดสรร แต่ให้การรับประกันว่าองค์ประกอบทั้งหมดมีประเภทเดียว

มีเครื่องมือวัดที่ใช้งานง่ายสำหรับตรวจสอบสิ่งที่เอ็นจิน Javascript ทำงานภายในกับชนิดหรือไม่?

ไม่และนั่นเป็นความตั้งใจ ตามที่อธิบายไว้ข้างต้นเราไม่ต้องการให้คุณปรับแต่งโค้ดของคุณตามรูปแบบใด ๆ ที่ V8 สามารถเพิ่มประสิทธิภาพได้ดีเป็นพิเศษในวันนี้และเราไม่เชื่อว่าคุณต้องการทำเช่นนั้น ชุดของสิ่งต่าง ๆ สามารถเปลี่ยนแปลงได้ในทิศทางใดทิศทางหนึ่ง: หากมีรูปแบบที่คุณชอบใช้เราอาจปรับให้เหมาะสมสำหรับรุ่นในอนาคต (ก่อนหน้านี้เราเคยคิดที่จะเก็บจำนวนเต็ม 32 บิตที่ไม่มีกล่องเป็นองค์ประกอบ . แต่ทำงานที่ยังไม่ได้เริ่มดังนั้นจึงไม่มีสัญญา) และบางครั้งหากมีรูปแบบที่เราเคยใช้ในการปรับให้เหมาะสมในอดีตเราอาจตัดสินใจที่จะวางสิ่งนั้นลงหากมันได้รับในทางอื่นการเพิ่มประสิทธิภาพที่สำคัญ / มีผลกระทบมากกว่า นอกจากนี้การทำฮิวริสติกแบบอินไลน์ก็ยากที่จะทำให้ถูกต้อง ดังนั้นการตัดสินใจที่ถูกต้องในเวลาที่เหมาะสมคือพื้นที่ของการวิจัยอย่างต่อเนื่องและการเปลี่ยนแปลงที่สอดคล้องกับพฤติกรรมของเครื่องยนต์ / คอมไพเลอร์ ซึ่งทำให้เป็นอีกกรณีหนึ่งที่ทุกคนจะโชคร้าย (คุณและเรา) หากคุณใช้เวลามากในการปรับแต่งรหัสของคุณจนกว่าชุดของเบราว์เซอร์รุ่นปัจจุบันบางรุ่นจะทำการตัดสินใจโดยประมาณที่คุณคิดว่า (หรือรู้หรือไม่?) จะดีที่สุดเพียงกลับมาอีกครึ่งปีต่อมา เปลี่ยนฮิวริสติกของพวกเขาแล้ว

แน่นอนว่าคุณสามารถวัดประสิทธิภาพการทำงานของแอปพลิเคชันของคุณโดยรวมได้ - นั่นคือสิ่งที่สำคัญที่สุดไม่ใช่ตัวเลือกที่เครื่องมือสร้างขึ้นภายในโดยเฉพาะ ระวัง microbenchmarks เพราะมันทำให้เข้าใจผิด: หากคุณแยกโค้ดสองบรรทัดและเกณฑ์มาตรฐานเท่านั้นโอกาสก็คือว่าสถานการณ์จะแตกต่างกันพอสมควร (เช่นข้อเสนอแนะประเภทต่าง ๆ ) ที่เอ็นจิ้นจะทำการตัดสินใจแตกต่างกันมาก


2
ขอบคุณสำหรับคำตอบที่ยอดเยี่ยมนี้เป็นการยืนยันความสงสัยของฉันเกี่ยวกับการทำงานของสิ่งต่าง ๆ และที่สำคัญพวกเขาตั้งใจทำงาน ยังArray.sort()ไงก็ตามมีการโพสต์บล็อกอื่น ๆ เกี่ยวกับปัญหา "คำติชมประเภท" ที่คุณพูดถึงด้วยหรือไม่ ฉันชอบที่จะอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้
Joppy

ฉันไม่คิดว่าเราบล็อกเกี่ยวกับแง่มุมนั้น มันเป็นสิ่งที่คุณอธิบายไว้ในคำถามของคุณเอง: เมื่อมีการใช้งานบิวด์อินใน JavaScript พวกเขาจะ "เหมือนห้องสมุด" ในแง่ที่ว่าถ้าโค้ดที่แตกต่างกันเรียกพวกมันด้วยประเภทที่แตกต่างกัน บางครั้งมากกว่า มันไม่เพียง แต่และไม่ใช่ปัญหาใหญ่ที่สุดของเทคนิคนั้น ฉันแค่อยากจะบอกว่าฉันคุ้นเคยกับปัญหาทั่วไป
jmrk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.