Чи реалістична складність NPath понад шістнадцять октиліонів? Або я зламав інструмент?


13

Я щойно виміряв великий фрагмент коду PHP (1153 рядки) за допомогою PHPMD ( http://phpmd.org/ ), і це говорить мені, що код має складність NPath 16244818757303403077832757824.

Це схоже на моторошно велику кількість, що говорить про те, що, можливо, PHPMD якимось чином зламався. Чи навіть можливо, що фрагмент коду, написаний людьми, має таку високу складність NPath? Цикломатична складність - 351.

Дві важливі деталі -

  1. Це був процедурний код, змішаний з HTML, і PHPMD вимірює лише об'єктно-орієнтований код. Щоб обійти це, я загорнув увесь файл у класі з однією функцією - це є репрезентативним способом його використання.

  2. Файл складається з серії вкладених операторів перемикання, а всередині них багато if..else висловлювань - так це, звичайно, досить складно.

Редагувати

Хочу уточнити, що я не сумніваюся, чи PHPMD брехає мені. Я знаю, що код - жахливий безлад, я просто цікавлюсь, чи можливо який-небудь код насправді такий поганий. Здається, відповідь "так", це дуже можливо.


2
Я не знаю, чи зламали ви інструмент, але №2 вказує, що код, ймовірно, може бути трохи відремонтований.
LindaJeanne

1
@LindaJeanne Я згоден. Я просто цікаво , як точно , скільки безлад це в.
Їжак

2
WordPress ' WP_Query::get_posts()була складність NPath з 1,435 Quindecillion в 2013 році ще гірше , в даний час ...
FUXIA

@toscho - це моя нова улюблена інформація. Спасибі!
Їжак

Відповіді:


24

Це цілком можливо. Припустимо, у нас є 35 конструкцій корпусів комутаторів з 10 випадків кожен, що дасть нам грубу циклічну складність 350, коли кожен перемикач відбувається один за іншим. Перший перемикач дає нам 10 шляхів. Другий перемикач дає нам ще 10 незалежних контурів, так що до нас є 10 · 10 шляхів. За допомогою третього перемикача ми отримуємо 10 · 10 · 10 = 10³ шляхів і так далі, поки не отримаємо 10 35 контурів! Це навіть вище, ніж ваш результат 1,6 · 10 28 шляхів, що, ймовірно, пов'язано з різним коефіцієнтом розгалуження, а також через вкладені оператори потоку управління, які зменшують кількість шляхів через ваш код.

Як найгірший сценарій для даної цикломатичної складності c, ми можемо мати максимум 2 c ациклічні шляхи через код (тут: 2 351 = 4,6 · 10 105 ).

Судження інструменту зрозуміло: код, з яким ви маєте справу, - це суперечливий, нестабільний і незрозумілий безлад. Подумайте про поділ його на менші, незалежні функції та абстрагування від повторення. Наприклад, ви можете відокремити генерацію HTML від основної логіки вашого PHP-сценарію.


14
Дякую за аналіз Я відчуваю потребу зазначити, що це не мій код ... але, як це часто буває, це здається мені моєю проблемою.
Єз

1
@Jez, якщо це якесь втіху, ти не в унікальному положенні.
Даніель Холлінрак

5

Згідно з цим описом , складність NPath є експоненціальною в цикломатичній складності.

Якщо зробити заяви просто, якщо у вас є два з цих тверджень, це по суті чотири маршрути через ваш код, що відповідають чотирьом можливим комбінаціям true / false для двох умов оператора. Додайте інше, якщо заява, і ви отримаєте 8.

Іншими словами, якби вся ваша цикломатична і NPath складність виходила з довгого списку тверджень if, то ваше рівняння було б NPath = 2^cyclomatic. Порівнюючи це з вашими числами, 2 ^ 351 = 4,6 * 10 ^ 105, набагато вище, ніж складність NPath, про яку ви повідомили.

Я не знаю, скільки робить PHPMD, щоб уникнути підрахунку шляхів, які насправді неможливі (наприклад, два взаємовиключні умови, обидва оцінюють як істинні). Можливо, ручний аналіз виявить, що багато шляхів насправді неможливо, тому код написаний таким чином, що надуває метрику NPath. Щоб продовжити вище, якщо у вас був список 351, якщо заяви, але ви могли перевірити, що тільки один коли-небудь був фактично введений, ви можете перетворити його на ланцюжок, якщо ... інакше тверджень, що збільшить вашу складність NPath вниз від 4,6 * 10 ^ 105 до 353.

Але, маючи лише інформацію у вашому запитанні, не знаючи, скільки такого спрощення можна було б зробити або вже проводити PHPMD, число видається реалістичним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.