ความซับซ้อนของ NPath นั้นมีความสมจริงมากกว่าสิบหกล้านหรือไม่ หรือฉันหักเครื่องมือหรือไม่


13

ฉันเพิ่งวัดโค้ด PHP ขนาดใหญ่ (1153 บรรทัด) โดยใช้ PHPMD ( http://phpmd.org/ ) และมันบอกรหัสว่ามีความซับซ้อนของ NPath เป็น 1624481875730340307783275782424

ดูเหมือนว่าเป็นจำนวนมากอย่างบ้าคลั่งสำหรับฉันชี้ให้เห็นว่าบางที PHPMD อาจจะพังในบางวิธี เป็นไปได้ไหมที่ชิ้นส่วนของโค้ดที่มนุษย์เขียนขึ้นมีความซับซ้อน NPath สูงเช่นนี้? ความซับซ้อนของวัฏจักรเท่ากับ 351

สองรายละเอียดที่สำคัญอาจ -

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

  2. ไฟล์นี้ประกอบไปด้วยชุดของคำสั่งสวิตช์ที่ซ้อนกันและภายในนั้นมีคำสั่ง if ..else มากมาย - ดังนั้นมันค่อนข้างซับซ้อนอย่างแน่นอน

แก้ไข

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


2
ฉันไม่รู้ว่าคุณทำลายเครื่องมือได้หรือไม่ แต่ # 2 บ่งชี้ว่ารหัสอาจจะสามารถได้รับการปรับปรุงใหม่ได้เล็กน้อย
LindaJeanne

1
@LindaJeanne ฉันเห็นด้วย ฉันแค่อยากรู้อยากเห็นว่าเป็นระเบียบมากเพียงใด
Jez

2
WordPress WP_Query::get_posts()มีความซับซ้อนของ NPath ที่ 1.435 ล้านล้านในปี 2013 มันยิ่งเลวร้ายลงในปัจจุบัน ...
fuxia

@toscho นั่นเป็นข้อมูลใหม่ที่ฉันโปรดปราน ขอบคุณ!
Jez

คำตอบ:


24

นี่เป็นไปได้ทั้งหมด สมมติว่าเรามีโครงสร้างสวิตช์ 35 ตัวแต่ละกรณี 10 อันซึ่งจะให้ความซับซ้อนของวงจรคร่าวๆที่ 350 เมื่อสวิตช์เกิดขึ้นหนึ่งอัน สวิตช์แรกให้เส้นทางแก่เรา 10 เส้นทาง สวิตช์ที่สองให้เส้นทางอิสระอีก 10 เส้นทางเพื่อให้เรามี 10 - 10 เส้นทางจนกระทั่งถึงที่นี่ เมื่อใช้สวิตช์ตัวที่สามเราจะได้รับ 10 · 10 · 10 = 10³เส้นทางและต่อไปเรื่อย ๆ จนกว่าเราจะได้รับ 10 35เส้นทางโดยรวม! นี่ยิ่งสูงกว่าผลลัพธ์ของคุณที่ 1.6 · 10 28 พาธ ซึ่งอาจเกิดจากปัจจัยการแตกแขนงที่แตกต่างกันและเนื่องมาจากคำสั่งควบคุมการไหลซ้อนกันซึ่งจะลดจำนวนเส้นทางผ่านรหัสของคุณ

ในฐานะที่เป็นสถานการณ์กรณีที่เลวร้ายที่สุดสำหรับให้ cyclomatic ซับซ้อนคเราสามารถมีได้สูงสุด 2 เส้นทางวัฏจักรรหัสผ่าน (ที่นี่: 2 351 = 4.6 · 10 105 )

การตัดสินของเครื่องมือนั้นชัดเจน: รหัสที่คุณติดต่อด้วยนั้นเป็นระเบียบที่ซับซ้อนไม่สามารถตรวจสอบได้และไม่สามารถทำลายได้ พิจารณาแยกเป็นขนาดเล็กฟังก์ชั่นที่เป็นอิสระและการทำซ้ำออกไป เช่นคุณสามารถแยกการสร้าง HTML ออกจากตรรกะหลักของสคริปต์ PHP ของคุณ


14
ขอบคุณสำหรับการวิเคราะห์ ฉันรู้สึกว่าจำเป็นที่จะต้องชี้ให้เห็นว่ามันไม่ใช่รหัสของฉัน ... แต่ตามปกติแล้วมันจะปรากฏปัญหาให้ฉัน
Jez

1
@Jez ถ้ามันเป็นปลอบใจคุณไม่ได้อยู่ในตำแหน่งที่ไม่ซ้ำกัน
Daniel Hollinrake

5

ตามคำอธิบายนี้ความซับซ้อนของ NPath นั้นอธิบายได้ในความซับซ้อนของวัฏจักร

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

กล่าวอีกนัยหนึ่งถ้าความซับซ้อนของ cyclomatic และ NPath ทั้งหมดของคุณมาจากรายการคำสั่ง if ที่มีความNPath = 2^cyclomaticยาว เปรียบเทียบกับตัวเลขของคุณ 2 ^ 351 = 4.6 * 10 ^ 105 ไกลสูงกว่าความซับซ้อนของ NPath ที่คุณรายงาน

ฉันไม่รู้ว่า PHPMD ทำอะไรได้บ้างเพื่อหลีกเลี่ยงการนับเส้นทางซึ่งเป็นไปไม่ได้จริง ๆ (เช่นสองเงื่อนไขที่ไม่เกิดร่วมกันซึ่งทั้งคู่ประเมินว่าเป็นจริง) อาจเป็นไปได้ว่าการวิเคราะห์ด้วยตนเองจะเปิดเผยว่าเส้นทางจำนวนมากเป็นไปไม่ได้จริงดังนั้นรหัสจึงถูกเขียนขึ้นในลักษณะที่ทำให้ตัวชี้วัด NPath พองตัว เพื่อดำเนินการต่อไปหากคุณมีรายการ 351 รายการหาก แต่สามารถตรวจสอบได้ว่ามีเพียงรายการเดียวที่เคยเข้ามาจริงคุณสามารถเปลี่ยนให้เป็นห่วงโซ่ของถ้า ... ข้อความสั่งอื่นทำให้ความซับซ้อนของ NPath ลดลงจาก 4.6 * 10 ^ 105 ถึง 353

แต่มีเพียงข้อมูลในคำถามของคุณเท่านั้นที่ไม่ทราบว่าการทำให้เข้าใจง่ายแบบนั้นสามารถทำได้หรือกำลังดำเนินการโดย PHPMD ตัวเลขดูเหมือนจริง

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