È realistica una complessità NPath di oltre sedici ottilioni? O ho rotto lo strumento?


13

Ho appena misurato una grande porzione di codice PHP (1153 righe) usando PHPMD ( http://phpmd.org/ ) e mi dice che il codice ha una complessità NPath di 16244818757303403077832757824.

A me sembra un numero follemente grande, il che suggerisce che forse PHPMD si è rotto in qualche modo. È anche possibile che un pezzo di codice scritto dagli umani abbia una complessità NPath così elevata? La complessità ciclomatica è 351.

Due dettagli forse importanti:

  1. Questo era un codice procedurale, mescolato con HTML, e PHPMD misurerà solo il codice orientato agli oggetti. Per ovviare a questo, ho racchiuso l'intero file in una classe con una singola funzione - questo è rappresentativo di come viene utilizzato.

  2. Il file è costituito da una serie di istruzioni switch nidificate e al suo interno ci sono molte istruzioni if..else, quindi è certamente piuttosto complicato.

modificare

Voglio chiarire che non mi sto chiedendo se PHPMD mi sta mentendo. So che il codice è un disastro terribile, mi chiedo solo se è possibile che un codice sia davvero così male. Sembra che la risposta sia sì, è molto possibile.


2
Non so se hai rotto lo strumento, ma # 2 indica che probabilmente il codice potrebbe essere leggermente modificato.
LindaJeanne,

1
@LindaJeanne Sono d'accordo. Sono solo curioso di sapere esattamente quanto sia un casino.
Jez,

2
WordPress " WP_Query::get_posts()aveva una complessità NPath di 1.435 Quindecilioni nel 2013. Oggi è anche peggio ...
fuxia,

@toscho è la mia nuova informazione preferita. Grazie!
Jez,

Risposte:


24

Questo è del tutto possibile. Supponiamo di avere 35 costrutti di caso di commutazione di 10 casi ciascuno, il che ci darebbe una complessità ciclomatica approssimativa di 350 quando ogni interruttore si verifica uno dopo l'altro. Il primo interruttore ci dà 10 percorsi. Il secondo interruttore ci fornisce altri 10 percorsi indipendenti, in modo che abbiamo 10 · 10 percorsi fino a qui. Con il terzo interruttore, otteniamo 10 · 10 · 10 = 10³ percorsi, e così via fino a ottenere 10 35 percorsi in totale! Questo è persino superiore al risultato di 1.6 · 10 28 percorsi, probabilmente a causa di un diverso fattore di ramificazione e a causa di istruzioni di flusso di controllo nidificate che riducono il numero di percorsi attraverso il codice.

Come scenario peggiore per una data complessità ciclomatica c, possiamo avere un massimo di 2 c percorsi aciclici attraverso il codice (qui: 2 351 = 4.6 · 10 105 ).

Il giudizio dello strumento è chiaro: il codice con cui hai a che fare è un disordine contorto, non verificabile e non mantenibile. Valuta di dividerlo in funzioni più piccole e indipendenti e di sottrarre ripetizioni. Ad esempio, potresti separare la generazione HTML dalla logica principale del tuo script PHP.


14
Grazie per l'analisi Sento la necessità di sottolineare che non è il mio codice ... ma, come spesso accade, mi sembra il mio problema.
Jez,

1
@Jez, se è una consolazione non ti trovi in ​​una posizione unica.
Daniel Hollinrake,

5

Secondo questa descrizione , la complessità NPath è esponenziale nella complessità ciclomatica.

Prendendo semplicemente istruzioni if, se si hanno due di queste istruzioni, si tratta essenzialmente di 4 rotte attraverso il codice corrispondenti alle quattro possibili combinazioni di vero / falso per le due condizioni di istruzione. Aggiungi un'altra istruzione if e ottieni 8.

In altre parole, se tutta la complessità ciclomatica e NPath provenisse da una lunga lista di istruzioni if, allora la tua uguaglianza sarebbe NPath = 2^cyclomatic. Confrontandolo con i tuoi numeri, 2 ^ 351 = 4,6 * 10 ^ 105, molto, molto più alto della complessità NPath che hai riportato.

Non so quanto PHPMD faccia per evitare il conteggio di percorsi che sono in realtà impossibili (ad esempio due condizionali che si escludono a vicenda entrambi valutando su true). Forse un'analisi manuale rivelerebbe che molti percorsi sono effettivamente impossibili, quindi il codice è scritto in un modo che gonfia la metrica NPath. Per continuare quanto sopra, se avessi un elenco di 351 istruzioni if, ma potresti verificare che solo una sia mai stata effettivamente immessa, potresti trasformarla in una catena di istruzioni if ​​... else, portando la complessità NPath a partire da 4.6 * 10 ^ 105 a 353.

Ma con solo le informazioni nella tua domanda, non sapendo quanto di quel tipo di semplificazione potrebbe essere fatto o è già stato fatto da PHPMD, il numero sembra realistico.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.