¿Es realista una complejidad NPath de más de dieciséis octillones? ¿O me he roto la herramienta?

13

Acabo de medir una gran parte del código PHP (1153 líneas) usando PHPMD ( enlace ) y me dice que el código tiene un NPath complejidad de 16244818757303403077832757824.

Me parece un número locamente grande, lo que sugiere que quizás el PHPMD se haya roto de alguna manera. ¿Es posible que un fragmento de código escrito por humanos tenga una complejidad de NPath tan alta? La complejidad ciclomática es 351.

Dos detalles posiblemente importantes -

  1. Este fue un código de procedimiento, mezclado con HTML, y PHPMD solo medirá el código orientado a objetos. Para solucionar esto, envolví todo el archivo en una clase con una sola función: esto es representativo de cómo se usa.

  2. El archivo consta de una serie de sentencias de switch anidadas, y dentro de ellas hay muchas sentencias if ... else, por lo que es bastante complicado.

Editar

Quiero aclarar que no estoy cuestionando si PHPMD me está mintiendo. Sé que el código es un desastre terrible, me pregunto si es posible que algún código sea realmente tan malo. Parece que la respuesta es sí, es muy posible.

    
pregunta Jez 14.05.2015 - 13:12

2 respuestas

24

Esto es completamente posible. Supongamos que tenemos 35 construcciones de cajas de interruptores de 10 casos cada una, lo que nos daría una complejidad ciclomática aproximada de 350 cuando cada cambio ocurra uno después del otro. El primer interruptor nos da 10 caminos. El segundo interruptor nos da otras 10 rutas independientes, de modo que tenemos 10 · 10 rutas hasta aquí. Con el tercer interruptor, obtenemos 10 · 10 · 10 = 10³ rutas, y así sucesivamente hasta que obtengamos 10 35 en total. Esto es incluso más alto que el resultado de 1.6 · 10 28 , lo que probablemente se deba a un factor de bifurcación diferente, y se debe a declaraciones de flujo de control anidadas que reducen el número de rutas a través de su código.

En el peor de los casos para una complejidad ciclomática c dada, podemos tener un máximo de 2 c rutas acíclicas a través del código (aquí: 2 351 = 4.6 · 10 105 ).

El criterio de la herramienta es claro: el código con el que estás lidiando es un lío complicado, no comprobable e inalcanzable. Considere dividirlo en funciones más pequeñas e independientes y abstraer la repetición. P.ej. podría separar la generación de HTML de la lógica principal de su script PHP.

    
respondido por el amon 14.05.2015 - 13:40
5

Según esta descripción , la complejidad de NPath es exponencial en la complejidad ciclomática.

Tomando simplemente simples declaraciones if, si tiene dos de estas declaraciones, eso es esencialmente 4 rutas a través de su código correspondiente a las cuatro combinaciones posibles de verdadero / falso para las dos condiciones de la declaración. Agrega otra instrucción if y obtienes 8.

En otras palabras, si toda su complejidad ciclomática y NPath provenga de una larga lista de sentencias if, entonces su igualación sería NPath = 2^cyclomatic . Comparando eso con tus números, 2 ^ 351 = 4.6 * 10 ^ 105, mucho, mucho más alto que la complejidad NPath que reportaste.

No sé cuánto hace PHPMD para evitar contar las rutas que en realidad son imposibles (por ejemplo, dos condicionales mutuamente excluyentes que se evalúan como verdaderos). Es posible que un análisis manual revele que muchas de las rutas son en realidad imposibles, por lo que el código está escrito de una manera que infla la métrica NPath. Para continuar con lo anterior, si tuviera una lista de 351 declaraciones if, pero pudiera verificar que solo se haya ingresado alguna vez, podría convertirla en una cadena de declaraciones if ... else, reduciendo la complejidad de su NPath de 4.6 * 10 ^ 105 a 353.

Pero con solo la información en su pregunta, sin saber qué tanto de ese tipo de simplificación podría hacerse o si ya lo está haciendo el PHPMD, el número parece realista.

    
respondido por el Ben Aaronson 14.05.2015 - 13:39

Lea otras preguntas en las etiquetas