2012-08-01 19 views
8

Tôi đã tự hỏi nếu có một sự khác biệt hiệu suất lớn trong các ngôn ngữ, cho dù bạn nên đặt nhiều khả năng được thực thi mã trong các if hoặc trong các khoản else. Dưới đây là một ví dụ:Nếu và người nào khác, tôi có nên đặt phần khả dĩ hơn không?

// x is a random number, or some key code from the user 
if(!somespecific_keycode) 
    do the general stuff 
else 
    do specific stuff 

và các giải pháp khác

if(somespecific_keycode) 
    do the specific stuff 
else 
    do general stuff 
+0

Điều đó phụ thuộc rất nhiều vào trình biên dịch, phiên bản trình biên dịch, các tùy chọn tối ưu hóa bạn đã chọn và đôi khi chỉ cần thời tiết. Nhưng trong 99.999% của tất cả các trường hợp trong thế giới thực, tôi có thể nghĩ rằng bạn sẽ hầu như không nhận thấy sự khác biệt. –

+0

Sẽ có sự khác biệt về hiệu suất ... trên thang điểm ** NANOSECONDS! ** Điều đó sẽ không đáng chú ý đối với bất kỳ ai ngoại trừ siêu nhân. – Marlon

Trả lời

6

Ưu tiên đặt chúng theo thứ tự làm cho mã rõ ràng hơn, thường có nhiều khả năng được thực thi trước.

+2

Hỗ trợ đầy đủ câu trả lời này. Các tổ chức tốt với các quy ước mã hóa phức tạp sẽ bao gồm điều này vào các quy tắc –

+0

Tôi không đồng ý. Câu hỏi đặt ra là về hiệu suất. –

1

ngành dự đoán sẽ gây ra một trong những để có nhiều khả năng và nó sẽ gây ra một sự khác biệt hiệu suất nếu bên trong một vòng lặp. Nhưng chủ yếu là bạn có thể bỏ qua điều đó nếu bạn không suy nghĩ ở cấp độ lắp ráp.

3

Trừ khi bạn gặp phải sự cố về hiệu suất, đừng lo lắng về điều đó.

Nếu bạn gặp sự cố về hiệu suất, hãy thử chuyển đổi chúng xung quanh và đo biến thể nào nhanh hơn, nếu có.

1

Quy tắc chung là đặt trường hợp có khả năng cao hơn trước, được coi là dễ đọc hơn.

0

Nó hầu như không tạo sự khác biệt nhưng đôi khi nó dễ đọc hơn và gỡ lỗi nếu if của bạn đang kiểm tra xem cái gì là đúng hay bằng nhau và người khác xử lý khi đó không phải là trường hợp.

0

Như những người khác đã nói, nó sẽ không tạo ra sự khác biệt lớn trừ khi bạn đang sử dụng nhiều lần này (trong một vòng lặp chẳng hạn). Trong trường hợp đó, đặt điều kiện khả dĩ nhất trước tiên vì nó sẽ có cơ hội sớm nhất để thoát khỏi tình trạng kiểm tra tình trạng.

Nó trở nên rõ ràng hơn khi bạn bắt đầu có nhiều thứ khác nếu có.

7

Như những người khác đã nói: về hiệu suất, bạn nên dựa vào trình biên dịch và phần cứng của bạn (dự đoán chi nhánh, thực thi đầu cơ) để làm điều đúng.

Trong trường hợp bạn thực sự lo ngại rằng hai điều này không giúp bạn đủ, GCC cung cấp builtin (__builtin_expect) mà bạn có thể chỉ rõ kết quả mong đợi của một chi nhánh.

Về mặt khả năng đọc mã, cá nhân tôi thích trường hợp có khả năng hơn ở trên cùng.

+0

Tôi đã bỏ phiếu cho câu trả lời này và sẽ tốt hơn nếu bạn giải thích cách sử dụng __builtin_expect và đưa ra một ví dụ. –

+0

mà chỉ đếm, khi trình biên dịch biết cái nào có thể xảy ra hơn, khi nói đến đầu vào của người dùng, người lập trình biết tốt nhất whats tùy chọn khả dĩ nhất người dùng sẽ chọn –

+0

Ví dụ cho __builtin_expect() có thể tìm thấy trong tài liệu tôi đã liên kết đến. – BjoernD

0

Bất kỳ sự khác biệt nào có thể phát sinh có liên quan nhiều hơn đến ngữ cảnh hơn là với các cấu trúc if-else. Vì vậy, tốt nhất bạn có thể làm ở đây là phát triển các bài kiểm tra của riêng bạn để phát hiện bất kỳ sự khác biệt nào.

Trừ khi bạn đang tối ưu hóa hệ thống hoặc phần mềm đã hoàn thành, tôi khuyên bạn nên tránh tối ưu hóa sớm. Có lẽ bạn đã nghe nói họ là ác.

0

AFAIK với trình biên dịch C tối ưu hóa hiện đại không có mối quan hệ trực tiếp giữa cách bạn tổ chức if hoặc vòng lặp và hướng dẫn phân nhánh thực tế trong mã được tạo. Hơn nữa các CPU khác nhau có các thuật toán dự đoán nhánh khác nhau.

Do đó:

  • Không tối ưu hóa cho đến khi bạn thấy hiệu suất xấu liên quan đến mã này

  • Nếu bạn tối ưu hóa, đo lường và so sánh các phiên bản khác nhau

  • Sử dụng dữ liệu thực tế của các đặc điểm khác nhau để đo lường hiệu suất

  • Nhìn vào mã lắp ráp tạo ra d bởi trình biên dịch của bạn trong cả hai trường hợp.

0

này không nhất thiết phải là một mối quan tâm thực hiện, nhưng tôi thường đi từ cụ thể để chung để ngăn chặn những trường hợp như thế này:

int i = 15; 

if(i % 3 == 0) 
    System.out.println("fizz"); 
else if(i % 5 == 0) 
    System.out.println("buzz"); 
else if(i % 3 == 0 && i % 5 == 0) 
    System.out.println("fizzbuzz"); 

đây các mã trên sẽ không bao giờ nói 'fizzbuzz', bởi vì 15 khớp với cả hai điều kiện i % 3 == 0i % 5 == 0. Nếu bạn xếp lại thứ tự thành một cái gì đó cụ thể hơn:

int i = 15; 

if(i % 3 == 0 && i % 5 == 0) 
    System.out.println("fizzbuzz"); 
else if(i % 3 == 0) 
    System.out.println("fizz"); 
else if(i % 5 == 0) 
    System.out.println("buzz"); 

Bây giờ các mã trên sẽ đạt được "fizzbuzz" trước khi bắt dừng lại bởi các điều kiện tổng quát hơn

0

Tất cả các câu trả lời có điểm hợp lệ. Dưới đây là một thêm một:

  • Tránh phủ định kép: nếu không này, sau đó, một cái gì đó khác có xu hướng thể gây nhầm lẫn cho người đọc. Do đó cho ví dụ được đưa ra, tôi sẽ ủng hộ:

    if (somespecific_keycode) { 
        do_the_specific_stuff(); 
    } else { 
        do_general_stuff(); 
    } 
    
Các vấn đề liên quan