Là một phức tạp NPath của hơn mười sáu triệu thực tế? Hoặc tôi đã phá vỡ công cụ?


13

Tôi vừa đo được một đoạn mã PHP lớn (1153 dòng) bằng PHPMD ( http://phpmd.org/ ) và nó cho tôi biết mã có độ phức tạp NPath là 16244818757303403077832757824.

Điều đó có vẻ như là một con số lớn điên rồ đối với tôi, cho thấy rằng có lẽ PHPMD đã bị phá vỡ theo một cách nào đó. Thậm chí có thể một đoạn mã được viết bởi con người có độ phức tạp NPath cao như vậy không? Độ phức tạp chu kỳ là 351.

Hai chi tiết quan trọng có thể -

  1. Đây là mã thủ tục, được trộn lẫn với HTML và PHPMD sẽ chỉ đo mã hướng đối tượng. Để giải quyết vấn đề này, tôi đã gói toàn bộ tệp trong một lớp bằng một hàm duy nhất - đây là đại diện cho cách sử dụng.

  2. Tệp này bao gồm một loạt các câu lệnh chuyển đổi lồng nhau, và bên trong chúng có rất nhiều câu lệnh if..else - vì vậy nó chắc chắn khá phức tạp.

Biên tập

Tôi muốn làm rõ rằng tôi không đặt câu hỏi liệu PHPMD có nói dối tôi không. Tôi biết rằng mã là một mớ hỗn độn khủng khiếp, tôi chỉ tự hỏi liệu có thể có mã nào thực sự tệ đến vậy không. Có vẻ như câu trả lời là có, nó rất có thể.


2
Tôi không biết nếu bạn đã phá vỡ công cụ, nhưng # 2 chỉ ra rằng mã có thể sẽ được tái cấu trúc một chút.
LindaJeanne

1
@LindaJeanne Tôi đồng ý. Tôi chỉ tò mò về chính xác bao nhiêu của một mớ hỗn độn.
Jez

2
WordPress ' WP_Query::get_posts()độ phức tạp NPath là 1.435 Quindecillion vào năm 2013. Ngày nay thậm chí còn tệ hơn nữa
Fuxia

@toscho đó là thông tin yêu thích mới của tôi. Cảm ơn!
Jez

Câu trả lời:


24

Điều này là hoàn toàn có thể. Giả sử chúng ta có 35 cấu trúc trường hợp chuyển đổi gồm 10 trường hợp, mỗi trường hợp sẽ tạo cho chúng ta độ phức tạp chu kỳ 350 khi mỗi lần chuyển đổi xảy ra lần lượt. Công tắc đầu tiên cho chúng ta 10 đường dẫn. Công tắc thứ hai cung cấp cho chúng tôi 10 đường dẫn độc lập khác, để chúng tôi có 10 đường dẫn 10 · cho đến đây. Với công tắc thứ ba, chúng tôi nhận được 10 · 10 · 10 = 10³ đường dẫn, và cứ như vậy cho đến khi chúng tôi có tổng cộng 10 35 đường dẫn! Điều này thậm chí còn cao hơn kết quả của 1.6 · 10 28 đường dẫn, có thể là do một yếu tố phân nhánh khác và do các câu lệnh luồng điều khiển lồng nhau làm giảm số lượng đường dẫn qua mã của bạn.

Như một trường hợp xấu nhất đối với độ phức tạp chu kỳ c đã cho, chúng ta có thể có tối đa 2 c đường đi theo chu kỳ thông qua mã (ở đây: 2 351 = 4.6 · 10 105 ).

Phán quyết của công cụ rất rõ ràng: mã bạn đang xử lý là một mớ hỗn độn, không thể kiểm chứng và không thể nhầm lẫn. Xem xét tách nó thành các chức năng nhỏ hơn, độc lập và trừu tượng hóa sự lặp lại. Ví dụ: bạn có thể tách thế hệ HTML khỏi logic chính của tập lệnh PHP của bạn.


14
Cảm ơn đã phân tích. Tôi cảm thấy cần phải chỉ ra rằng đó không phải của tôi ... nhưng, như thường lệ, nó xuất hiện với tôi vấn đề của tôi.
Jez

1
@Jez, nếu đó là bất kỳ sự an ủi nào thì bạn không ở một vị trí duy nhất.
Daniel Hollinrake

5

Theo mô tả này , độ phức tạp NPath là hàm mũ theo độ phức tạp chu kỳ.

Chỉ đơn giản là các câu lệnh if, nếu bạn có hai trong số các câu lệnh này, về cơ bản đó là 4 tuyến thông qua mã của bạn tương ứng với bốn kết hợp đúng / sai có thể có trong hai điều kiện câu lệnh. Thêm một câu lệnh if và bạn nhận được 8.

Nói cách khác, nếu tất cả độ phức tạp chu kỳ và NPath của bạn đến từ một danh sách dài các câu lệnh if, thì phương trình của bạn sẽ là NPath = 2^cyclomatic. So sánh với số của bạn, 2 ^ 351 = 4.6 * 10 ^ 105, xa, cao hơn nhiều so với độ phức tạp NPath mà bạn đã báo cáo.

Tôi không biết có bao nhiêu PHPMD để tránh đếm các đường dẫn thực sự không thể (ví dụ: hai điều kiện loại trừ lẫn nhau đều đánh giá là đúng). Có thể một phân tích thủ công sẽ tiết lộ rằng rất nhiều đường dẫn thực sự là không thể, vì vậy mã được viết theo cách làm tăng chỉ số NPath. Để tiếp tục như trên, nếu bạn có một danh sách 351 câu lệnh if, nhưng có thể xác minh rằng chỉ có một câu lệnh thực sự được nhập, bạn có thể biến nó thành một chuỗi nếu ... câu lệnh khác, làm giảm độ phức tạp NPath của bạn xuống từ 4.6 * 10 ^ 105 đến 353.

Nhưng chỉ với thông tin trong câu hỏi của bạn, không biết bao nhiêu loại đơn giản hóa đó có thể được thực hiện hoặc đã được thực hiện bởi PHPMD, con số có vẻ thực tế.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.