ควรทดสอบความซับซ้อนของอัลกอริทึมหรือไม่ ถ้าเป็นเช่นนั้นได้อย่างไร


14

สมมติว่าฉันกำลังใช้สิ่งที่ง่ายเช่นการค้นหารายการ / แถวลำดับ ฟังก์ชั่น (ใน c #) จะมีลักษณะคล้ายกับ:

static int FindIndex(int[] sortedList, int i);

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

ดังนั้นคำถามของฉันคือ: เราควรพยายามเขียนการทดสอบที่รับประกันประสิทธิภาพในแง่ของความซับซ้อนของอัลกอริทึมและถ้าเป็นเช่นนั้นได้อย่างไร

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

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

มีคนอื่นที่คิดว่าสิ่งนี้ (อาจ)? ขอบคุณ


@ steenhulthin - ฉันจะปล่อยให้เคี่ยวนี้ที่นี่และตรวจสอบว่า ฉันไม่เคยไปที่นั่นมาก่อน
SirPentor

btw เป็นคำถามที่ดี +1
Rafael Colucci

คำตอบ:


13

ความซับซ้อนของอัลกอริทึมเป็นโครงสร้างทางทฤษฎีและเป็น "การทดสอบ" ที่ดีที่สุดด้วยดินสอและกระดาษ มันไม่สามารถทดสอบอย่างเป็นประโยชน์ได้

ประสิทธิภาพที่สมบูรณ์สามารถทดสอบได้โดยใช้กลไกและสามารถทำการทดสอบหน่วยที่เป็นประโยชน์ได้ หากประสิทธิภาพมีความสำคัญคุณสามารถระบุขีด จำกัด : "เคียวรีนี้ควรใช้เวลาไม่เกิน 50 มิลลิวินาทีในการเรียกใช้หมายเลข10 6และไม่เกิน 60 มิลลิวินาทีสำหรับหมายเลข10 7 " ที่คุณสามารถสร้างการทดสอบหน่วยสำหรับ

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


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

เพียงเพราะห้องสมุดให้การรับประกันบางอย่างไม่ได้หมายความว่าพวกเขาจะต้องผ่านการทดสอบหน่วย
svick

@Tobias Brick: ทดสอบบางสิ่งและกำหนดบางสิ่งเป็นสองสิ่งที่แตกต่างกัน
DeadMG

การแสดงให้เห็นถึงประสิทธิภาพนั้นยาก มันเกี่ยวข้องกับจุดตัวอย่างจำนวนมากสำหรับพารามิเตอร์ที่แตกต่างกัน มันง่ายกว่าเมื่อฟังก์ชั่นส่วนบุคคลไม่สำคัญ แต่ยิ่งไปกว่านั้น ... โหลด, RAM, ความเร็วบัสด้านหน้า, CPU, จำนวนคอร์, การรวบรวมคอมไพเลอร์, ความก้าวร้าวของคอมไพเลอร์, ระดับมลภาวะของรีจิสตรี ตัวอย่าง.
งาน

3

ในขณะที่ฉันไม่แน่ใจว่าเครื่องมือนี้จะเป็นประโยชน์อย่างยิ่งสำหรับการทดสอบหน่วยกระดาษ"Empirical Computational Complexity"โดย Goldsmith, Aiken และ Wilkerson อธิบายถึงวิธีการใช้รหัสและสังเกตพฤติกรรมแบบไดนามิกในชุดของอินพุตที่หลากหลายเพื่อสังเกตุ สืบทอดมาจากความซับซ้อนของซีมโทติค โปรแกรมที่อธิบายในเอกสารเป็นโอเพ่นซอร์สและมีให้ที่นี่ที่นี่

หวังว่านี่จะช่วยได้!


0

สิ่งสำคัญคือลองกับข้อมูลขนาดใหญ่และดูว่ามันใช้เวลานานเกินไป

ในประสบการณ์การปรับแต่งประสิทธิภาพของฉันเช่นในตัวอย่างนี้จะเกิดอะไรขึ้นถ้าอัลกอริทึมบางตัว (ตัวอย่าง) O (n ^ 2) มันอาจจะใช้ได้ตราบใดที่ร้อยละของเวลาที่ไม่เคยเข้าสู่เรดาร์

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

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


0

ฉันไม่คิดว่าสิ่งที่คุณต้องการจะทำคือการทดสอบหน่วย

AFAIK การทดสอบหน่วยเป็นเพียงเพื่อให้แน่ใจว่าโค้ดทำในสิ่งที่ควรทำและไม่ได้มุ่งเน้นที่ประสิทธิภาพ

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

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

มีบางคนที่ชอบการทดสอบประสิทธิภาพ (ซึ่งใช้การทดสอบความเครียดการทดสอบโหลดเป็นต้น)

คุณยังสามารถใช้เครื่องมือสร้างความเครียดร่วมกับเครื่องมือสร้าง (ant, studio build อัตโนมัติ) เป็นส่วนหนึ่งของขั้นตอนการปรับใช้ของคุณ (นั่นคือสิ่งที่ฉันทำ)

ดังนั้นคำตอบสั้น ๆ คือไม่คุณไม่ควรกังวลเกี่ยวกับเรื่องนั้นเมื่อหน่วยทดสอบรหัส


0

การส่งผ่านตัวเปรียบเทียบและการติดตามจำนวนครั้งที่มีการเรียกจะใช้งานได้ง่ายเช่นการตรวจสอบว่าจำนวนการเปรียบเทียบเมื่อทำการค้นหาในการป้อนข้อมูลแบบคงที่ (พูดnew int[] { 1,2,3, ... , 1024 }) ยังคงต่ำกว่า 10 อย่างน้อยก็จะ ทำให้ชัดเจนความตั้งใจของคุณเกี่ยวกับวิธีการที่อัลกอริทึมควรจะทำงาน

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

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