Una complessità NPath di oltre sedici ottillion è realistica? O ho rotto lo strumento?

13

Ho appena misurato una grande porzione di codice PHP (1153 linee) usando PHPMD ( link ) e mi dice che il codice ha un NPath complessità di 16244818757303403077832757824.

Questo mi sembra un numero follemente grande, suggerendo che forse PHPMD si è rotto in qualche modo. È persino 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 codice procedurale, mescolato con HTML, e PHPMD misurerà solo il codice orientato agli oggetti. Per ovviare a questo, ho avvolto 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, all'interno di quelle ci sono un sacco di istruzioni if..else, quindi è certamente piuttosto complicato.

Modifica

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

    
posta Jez 14.05.2015 - 13:12
fonte

2 risposte

24

Questo è interamente possibile. Supponiamo di avere 35 costrutti switch-case di 10 casi ciascuno, il che ci darebbe una complessità ciclomatica di 350 quando ogni switch si verifica uno dopo l'altro. Il primo interruttore ci dà 10 percorsi. Il secondo interruttore ci dà un altro 10 percorsi indipendenti, in modo da avere 10 · 10 percorsi fino a qui. Con il terzo interruttore, otteniamo 10 · 10 · 10 = 10³ percorsi, e così via fino a ottenere 10 percorsi 35 in totale! Questo è persino superiore al risultato dei percorsi 1.6 · 10 28 , probabilmente a causa di un diverso fattore di diramazione e a causa di istruzioni di flusso di controllo annidate 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 si ha a che fare è un pasticcio contorto, non testabile e non gestibile. Prendi in considerazione la possibilità di dividerlo in funzioni più piccole e indipendenti e di asportare la ripetizione. Per esempio. puoi separare la generazione di HTML dalla logica principale del tuo script PHP.

    
risposta data 14.05.2015 - 13:40
fonte
5

In base alla questa descrizione , la complessità di NPath è esponenziale nella complessità ciclomatica.

Prendendo semplicemente semplici istruzioni if, se hai due di queste affermazioni, questo è essenzialmente 4 percorsi attraverso il tuo codice corrispondente alle quattro possibili combinazioni di vero / falso per le due condizioni dell'istruzione. Aggiungi un'altra istruzione if e ottieni 8.

In altre parole, se tutta la tua complessità ciclomatica e NPath provenisse da un lungo elenco di istruzioni if, 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 segnalato.

Non so quanto PHPMD faccia per evitare il conteggio di percorsi che sono effettivamente impossibili (ad esempio, due condizionali che si escludono a vicenda valutando entrambi come veri). Forse un'analisi manuale rivelerebbe che molti dei percorsi sono effettivamente impossibili, quindi il codice è scritto in un modo che gonfia la metrica NPath. Per continuare quanto sopra, se avessi una lista di 351 se dichiarazioni, ma potessi verificare che solo una è stata effettivamente inserita, potresti trasformarla in una catena di if ... else statement, portando la complessità di NPath giù da 4.6 * 10 ^ 105 a 353.

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

    
risposta data 14.05.2015 - 13:39
fonte

Leggi altre domande sui tag