วิธีการวัดความซับซ้อนในทางปฏิบัติในโครงการซอฟต์แวร์ขนาดใหญ่ของคุณ?


11

ในมหาวิทยาลัยที่หลักสูตรอัลกอริทึมของเราเราเรียนรู้วิธีการคำนวณความซับซ้อนของอัลกอริทึมง่าย ๆ ที่ใช้ในการฝึกซ้อมเช่นตารางแฮชหรือการเรียงลำดับอย่างรวดเร็ว

แต่ตอนนี้ในโครงการซอฟต์แวร์ขนาดใหญ่เมื่อเราต้องการทำให้มันเร็วขึ้นสิ่งที่เราทำคือดูแต่ละชิ้น - วนซ้อนกันไม่กี่ห่วงที่สามารถแทนที่ด้วยตารางแฮชที่เร็วขึ้นการค้นหาช้าที่นี่ซึ่งสามารถเร่งความเร็วด้วย เทคนิคที่แปลกใหม่ - แต่เราไม่เคยคำนวณความซับซ้อนของท่อทั้งหมดของเรา

มีวิธีใดที่จะทำเช่นนั้น? หรือคนที่อยู่ในทางปฏิบัติเพียงอาศัย "ในพื้นที่" โดยใช้อัลกอริทึมแบบเร็วเพื่อทำให้แอปพลิเคชันทั้งหมดเร็วขึ้นแทนที่จะเป็นแอปทั่วโลกที่พิจารณาแอปพลิเคชันทั้งหมด?

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

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


1)สิ่งนี้ต้องใช้วิธีการทดสอบเพื่อค้นหาคะแนนที่จะปรับปรุง การทดสอบเกณฑ์มาตรฐานการทดสอบความทนทานการทดสอบแบบไดนามิก (โดยการตรวจสอบการวัดหน่วยความจำ / CPU ของแต่ละองค์ประกอบ) 2)หลังจากค้นหาคะแนนเพื่อปรับปรุงคุณจะพบสาเหตุของคะแนนเหล่านั้น 3)ค้นหาวิธีแก้ปัญหาเพื่อหาสาเหตุของสาเหตุรักษาความถูกต้อง
แลกเปลี่ยน

คุณต้องการเครื่องมือบางอย่างสำหรับการทดสอบเหล่านี้ที่กล่าวถึงในจุดที่ 1
overexchange

1
การวิเคราะห์ Big O ไม่ได้บอกคุณว่าอัลกอริทึมจะทำงานอย่างไร มันจะบอกคุณว่าประสิทธิภาพจะปรับขนาดตามที่nเพิ่มขึ้น
John Wu

คำตอบ:


5

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

ดังนั้นการเริ่มดูชิ้นส่วนบุคคลจึงเป็นวิธีที่ดีที่สุด นั่นเป็นเหตุผลที่การทำโปรไฟล์ (ตามที่อธิบายไว้ในคำตอบของ David Arno ) นั้นใช้ได้เนื่องจากช่วยให้คุณระบุรหัส 5% ที่กล่าวถึงซึ่งการปรับให้เหมาะสมจะทำให้คุณ "ปังใหญ่ที่สุดสำหรับเจ้าชู้" การปรับให้เหมาะสม "แอปพลิเคชันทั้งหมด" มีความเสี่ยงบางอย่างจากการ overengineering และถ้าคุณเพิ่มประสิทธิภาพ 95% แม้โดยปัจจัย 10 มันมักจะไม่มีผลที่วัดได้ โปรดสังเกตว่าการทำโปรไฟล์บอกคุณมากกว่าการประมาณความซับซ้อนของอัลกอริธึมเชิงสมมุติฐานเนื่องจากอัลกอริทึมแบบง่ายที่ต้องการขั้นตอน O (N ^ 3) ยังคงเร็วกว่าอัลกอริทึมที่ซับซ้อนซึ่งต้องใช้ O (N log (N)) ตราบใดที่ N มีขนาดเล็กพอ

หลังจากการทำโปรไฟล์เผยให้เห็นจุดร้อนใคร ๆ ก็สามารถปรับมันได้ แน่นอน "ฮอตสปอต" อาจใหญ่กว่าโค้ดเพียงหนึ่งหรือสองบรรทัดบางครั้งต้องแทนที่ส่วนประกอบทั้งหมดเพื่อให้เร็วขึ้น แต่โดยทั่วไปจะยังคงเป็นส่วนเล็ก ๆ ของรหัสฐานในโปรแกรมขนาดใหญ่ .

เทคนิคการเพิ่มประสิทธิภาพโดยทั่วไปรวมถึง

  • ปรับปรุงการใช้อัลกอริทึมและโครงสร้างข้อมูล

  • ปรับจูนของอดีต

  • การเพิ่มประสิทธิภาพขนาดเล็กที่จุดร้อนจริงบางแห่ง

  • การบันทึกส่วนที่สำคัญโดยใช้รหัสการประกอบหรือ CUDA

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


13

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

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


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

3
@FrankHileman ผมคิดว่าจุดที่นี่คือประสิทธิภาพการทำงานที่เป็นในทางปฏิบัติความกังวลและสามารถวัดได้จริง คุณไม่ได้ใช้คณิตศาสตร์เพื่อค้นหาคอขวดของซอฟต์แวร์แม้ว่าคุณอาจแก้ไขได้เมื่อใช้คณิตศาสตร์ (อัลกอริทึม)
Wildcard

ในบันทึกที่เกี่ยวข้องในการนำเสนอสไลด์โชว์แบบเก่า (สไลด์แก้ว) มีเทคโนโลยีที่แกล้งทำเป็นทั้งหมดว่าจะคำนวณความหนาแน่นเฉลี่ยของสไลด์โคมไฟทางคณิตศาสตร์เพื่อกำหนดความสว่างของแสงที่ใช้อย่างไร ไร้ประโยชน์โดยสิ้นเชิง: หากภาพไม่ปรากฏขึ้นมาอย่างดีคุณจะได้แสงที่สว่างขึ้น!
Wildcard

@Wildcard ในขณะที่ประสิทธิภาพสามารถวัดได้ในขณะใช้งานเท่านั้นสามารถทำนายได้แบบคงที่ ตัวเลือกที่แย่ของโครงสร้างข้อมูลอาจดูดีมีประสิทธิภาพชาญฉลาดในการทดสอบประสิทธิภาพ แต่ล้มเหลวอย่างน่าสังเวชในกรณีขอบที่สามารถทำนายได้ในการวิเคราะห์แบบคงที่ นี่คือเหตุผลเดียวกันที่เราดูการวิเคราะห์ความซับซ้อนของกรณีที่เลวร้ายที่สุดสำหรับโครงสร้างข้อมูลโดยทั่วไป
Frank Hileman

@ Wildcard: คุณถูกต้อง แต่ Frank ก็ยังถูกต้องมากที่โพสต์นี้ไม่ตอบคำถาม
Doc Brown

3

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

ขั้นตอนแรกของฉันคือการจับมือของฉันในแผนภาพรายละเอียดสถาปัตยกรรมหรือสร้างด้วยตัวเอง กำหนดว่าขั้นตอนใดบ้างที่องค์ประกอบใดในซอฟต์แวร์จะต้องใช้และใช้เวลานานแค่ไหนในแต่ละขั้นตอน

นอกจากนี้ให้หาวิธีที่ส่วนประกอบต่างๆมีปฏิสัมพันธ์ซึ่งกันและกัน สิ่งนี้สามารถสร้างความแตกต่างได้ทั้งหมด

ตัวอย่างเช่นฉันเคยเห็นโค้ดใน C # ที่ส่วนต่อประสานระหว่างสององค์ประกอบผ่าน IEnumerable ที่สร้างขึ้นโดยองค์ประกอบแรกซึ่งถูกระบุโดยองค์ประกอบที่สองแล้ว ใน C # ต้องใช้การสลับบริบทซึ่งอาจมีค่าใช้จ่ายสูงในบางกรณี การแก้มันไม่มีผลกระทบต่ออัลกอริทึม . ToList () แบบง่ายตรวจสอบให้แน่ใจว่ามีการรวบรวมผลลัพธ์ก่อนที่ขั้นตอนต่อไปจะแก้ไขปัญหานี้ได้

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

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