On altı oktilyonun üzerindeki NPath karmaşıklığı gerçekçi midir? Yoksa aracı kırdım mı?


13

Ben sadece PHPMD ( http://phpmd.org/ ) kullanarak PHP kodu (1153 satır) büyük bir yığın ölçtüm ve bana kod 16244818757303403077832757824 NPath karmaşıklığı olduğunu söylüyor.

Bu benim için çok büyük bir sayı gibi görünüyor, belki de PHPMD'nin bir şekilde kırıldığını gösteriyor. İnsanlar tarafından yazılan bir kod parçasının böyle yüksek bir NPath karmaşıklığına sahip olması bile mümkün müdür? Siklomatik karmaşıklık 351'dir.

Muhtemel önemli iki detay -

  1. Bu yordamsal koddu, HTML ile karıştırıldı ve PHPMD yalnızca nesne yönelimli kodu ölçecek. Bunu aşmak için, tüm dosyayı tek bir işlevle bir sınıfa sardım - bu nasıl kullanıldığını temsil eder.

  2. Dosya bir dizi iç içe anahtar ifadesinden oluşur ve bunların içinde if..else ifadelerinin birçoğu vardır - bu yüzden kesinlikle oldukça karmaşıktır.

Düzenle

PHPMD'nin bana yalan söyleyip söylemediğini sorgulamadığımı açıklığa kavuşturmak istiyorum. Kodun korkunç bir karışıklık olduğunu biliyorum, sadece herhangi bir kodun gerçekten bu kadar kötü olabileceğini merak ediyorum. Cevap evet gibi görünüyor, çok mümkün.


2
Eğer aracı kırdı bilmiyorum, ama # 2 kod muhtemelen biraz refactored için stand olabilir gösterir.
LindaJeanne

1
@LindaJeanne katılıyorum. Ben olarak merak ediyorum aynen İçinde ne kadar bir karmaşa.
Jez

2
WordPress'in 2013'te 1.435 Quindecillion NPath karmaşıklığıWP_Query::get_posts() vardı . Bugünlerde daha da kötü…
fuxia

@toscho benim yeni favori bilgim. Teşekkürler!
Jez

Yanıtlar:


24

Bu tamamen mümkündür. Farz edelim ki, her biri birbiri ardına gerçekleştiğinde 350 değerinde kaba bir siklomatik karmaşıklık verecek olan 10'ar vakadan 35 anahtar kutusu yapımız var. İlk anahtar bize 10 yol verir. İkinci anahtar bize başka bir bağımsız 10 yol verir, böylece buraya kadar 10 · 10 yolumuz vardır. Üçüncü anahtarla, toplam 10 35 yol elde edene kadar 10 · 10 · 10 = 10³ yol elde ederiz ! Bu, muhtemelen farklı bir dallanma faktörüne bağlı olan ve kodunuzdaki yol sayısını azaltan iç içe kontrol akış deyimleri nedeniyle 1.6 · 10 28 yol sonucunuzdan bile daha yüksektir .

Belirli bir siklomatik karmaşıklık c için en kötü senaryo olarak , kod aracılığıyla maksimum 2 c asiklik yol alabiliriz (burada: 2 351 = 4.6 · 10 105 ).

Aracın kararı açıktır: uğraştığınız kod kıvrımlı, test edilemez ve sürdürülemez bir karışıklıktır. Daha küçük, bağımsız işlevlere bölmeyi ve tekrarlamayı soyutlamayı düşünün. HTML üretimini PHP betiğinizin ana mantığından ayırabilirsiniz.


14
Analiz için teşekkürler. Bu benim kodum değil işaret gerek hissediyorum ... ama, sık sık olduğu gibi, bana sorunum görünüyor.
Jez

1
@Jez, herhangi bir teselli ise benzersiz bir konumda değilsiniz.
Daniel Hollinrake

5

Bu açıklamaya göre , NPath karmaşıklığı, siklomatik karmaşıklıkta üsteldir.

Sadece basit if ifadeleri, bu ifadelerden ikisine sahipseniz, bu iki deyim koşulu için doğru / false olan dört olası birleşime karşılık gelen kodunuz üzerinden 4 yol vardır. Başka bir if ifadesi ekleyin ve 8 kazanın.

Başka bir deyişle, tüm siklomatik ve NPath karmaşıklığınız if ifadelerinin uzun bir listesinden geliyorsa, eşitliğiniz olurdu NPath = 2^cyclomatic. Bunu sayılarınızla karşılaştırdığınızda, bildirdiğiniz NPath karmaşıklığından çok daha yüksek olan 2 ^ 351 = 4.6 * 10 ^ 105.

Ben aslında imkansız yolları sayma önlemek için ne kadar PHPMD yaptığını bilmiyorum (örneğin her ikisi de doğru değerlendirme iki karşılıklı özel koşul). Muhtemelen manuel bir analiz, birçok yolun aslında imkansız olduğunu ortaya çıkaracaktır, bu nedenle kod NPath metriğini şişirecek şekilde yazılmıştır. Yukarıdakilere devam etmek için, eğer 351 if ifadelerinin bir listesine sahip olduysanız, ancak sadece bir tanesinin gerçekten girildiğini doğrulayabilirseniz, NPath karmaşıklığınızı 4,6 * 10'dan aşağıya düşürerek if ... else ifadelerinin bir zincirine dönüştürebilirsiniz. ^ 105 ila 353.

Ancak yalnızca sorunuzdaki bilgilerle, bu tür basitleştirmenin ne kadarının yapılabileceğini veya PHPMD tarafından zaten yapıldığını bilmeden, sayı gerçekçi görünüyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.