2016-07-22 14 views
7

Ví dụ (Cho phép nói rằng chúng ta đang nói về C++ nếu điều đó tạo ra differnce), Trong một toán tử & & nếu tôi biết rằng một câu lệnh sẽ dẫn đến 0 thường xuyên hơn/có cơ hội cao hơn ở phía bên trái, và tuyên bố khác ở bên phải?Không ngắn mạch thực hiện chương trình nhanh hơn, và đang phân tích câu lệnh nào được đặt đầu tiên trong câu lệnh điều kiện có đáng giá không? Ví dụ:

Tương tự cho || nhà điều hành nếu tôi biết rằng một tuyên bố sẽ dẫn đến 1 thường xuyên hơn/có cơ hội cao hơn thì câu lệnh khác tôi nên đặt ở bên trái và câu lệnh khác bên phải? Bây giờ làm tất cả điều này sẽ gây ra rất nhiều thời gian phân tích chương trình, nhưng nếu điều này làm tăng tốc thời gian thực hiện cho chương trình là nó có giá trị thực hiện nó, và là cái gì mà các lập trình viên hệ thống nhúng/thời gian thực xem xét tăng tốc ứng dụng của họ nếu cần thiết?

+4

* là nó đáng làm * sẽ phụ thuộc vào rất nhiều yếu tố. Lớn nhất là chi phí để thực hiện điều chỉnh này là bao nhiêu và bạn tiết kiệm được bao nhiêu từ hiệu suất được thêm vào. – NathanOliver

+0

về nguyên tắc có, đó là lý do các nhà khai thác shortcircuit tồn tại – user463035818

+0

Đây có phải là nỗ lực cuối cùng để cải thiện hiệu suất trong các ứng dụng nhúng (có thời hạn khó) hay là một cái gì đó mà họ thực sự xem xét để cải thiện hiệu suất? –

Trả lời

4

Trước tiên, hãy chắc chắn rằng bạn không phải là nạn nhân của sớm tối ưu hóa .

Với điều đó đã nói, hãy đảm bảo rằng bạn đã làm mọi thứ có thể để tăng tốc độ nút cổ chai của chương trình.


Làm những gì bạn nói về ngắn mạch có thể là một ý tưởng hay trong một số trường hợp, nhưng điều đó phụ thuộc rất nhiều vào tất cả các câu lệnh của bạn.

Ví dụ, nếu bạn có một cái gì đó như:

if(slowFunction() && complexConditionRootsAndExponents && ConditionUsuallyZero) 

sau đó bạn có thể sẽ muốn điều đó hạn cuối cùng để là người đầu tiên, sẽ không bạn?

Tuy nhiên, hãy cẩn thận, mọi thứ không phải lúc nào cũng tầm thường để hoán vị theo trình tự hợp lý. Kiểm tra ví dụ câu trả lời của tôi trong Why this program printed fork 4 times?, nơi người ta có thể thấy rằng ngắn mạch có thể ảnh hưởng đến dòng chảy của việc thực hiện chương trình.


TL; DR

Nhìn chung, mặc dù nó hiếm khi có được tăng tốc đáng kể bởi hoán vị các điều khoản trong điều kiện này. Tập trung vào nút cổ chai của chương trình và giải quyết khó khăn nhất có thể!

+1

Cảm ơn bạn về ví dụ và tham khảo. Có, tôi không biết rằng tối ưu hóa sớm là một điều, tuy nhiên bây giờ tôi hiểu nó như là nút cổ chai nên được giải quyết đầu tiên! –

+1

Bạn được chào đón @OmidCompSCI. Bạn đã hỏi một câu hỏi hay, tôi cũng đã hỏi vài năm trước và tôi đã làm sai để cố gắng tối ưu hóa điều này, chứ không phải là nút cổ chai. Và nó không tạo ra sự khác biệt. Tuy nhiên, tối ưu hóa các nút cổ chai của chương trình của bạn chắc chắn sẽ mang lại kết quả tốt đẹp! :) Chúc may mắn. – gsamaras

3

Bạn cũng phải xem xét, đánh giá chi phí của mỗi bên là bao nhiêu.

if (veryCostlyOftenFalse() && veryCheapRareFalse()) // may be faster other way around 

Trừ khi trên 50% nguồn của bạn là đánh giá biểu thức và phân nhánh, tôi cho rằng đây là tối ưu hóa resort cuối cùng, khi bạn hài lòng với mọi thứ khác.


Các lập trình viên ứng dụng/thời gian thực nhúng tập trung khoảng theo thứ tự này:

  1. thuật toán tất nhiên, việc tìm kiếm hợp lý trade-off ở tốc độ vs vũ trụ.
  2. cấu trúc dữ liệu trong bộ nhớ (nhấn cache thường xuyên nhất có thể, khi được thực hiện bởi các thuật toán đó).
  3. lược tả ứng dụng thực với dữ liệu thực, để xem liệu có một số nút cổ chai không mong muốn và sửa chữa chúng không.
  4. nếu bạn đang tuyệt vọng mất tích ở đâu đó một hai đồng hồ hoặc, và có một số phức tạp if xung quanh, sau đó có, nó có thể giúp ...
+0

Cảm ơn bạn đã cho tôi biết những gì các lập trình viên nhúng/thời gian thực tập trung vào. –

4

Câu trả lời cho câu hỏi là: Có, nó tác động đến hiệu suất.

Có hay không hiệu suất đạt được đáng giá của việc tìm kiếm các vị trí có thể được cải thiện và thay đổi chương trình là điều duy nhất bạn có thể trả lời.

Trong hầu hết các trường hợp, thay đổi hiệu suất sẽ nhỏ, nhưng nếu một số hoạt động có liên quan là tốn kém, điều đó có thể đáng kể.

Xin lưu ý rằng cũng có thể có các hàm ý chính xác. Ví dụ: nếu trong if (foo() || bar()) điều quan trọng là bar không bao giờ được gọi nếu foo trả về true, thì đó sẽ là lỗi để sắp xếp lại các cuộc gọi.

Bắt đầu bằng cách đảm bảo chương trình của bạn là chính xác. Sau đó, nếu quá chậm; hồ sơ nó và tối ưu hóa, nơi nó sẽ có tác động lớn nhất. Điều đó có thể là thứ tự đánh giá trong bối cảnh ngắn mạch, nhưng trong hầu hết các trường hợp, nó sẽ là thứ khác.

+1

Cảm ơn bạn, có vẻ như việc tìm kiếm nút cổ chai quan trọng hơn là tìm kiếm những điều nhỏ nhặt này, vì có vẻ như Chi phí lớn hơn việc tìm kiếm những trường hợp này trong hầu hết các trường hợp. –

5

Điều đó tùy thuộc. Nếu tuyên bố là đơn giản như:

if(y == 4 || x == 2) 

và cho rằng tần số của x == 2 cao hơn rất nhiều, vì vậy mà chúng ta có thể có ngắn mạch thực hiện bằng cách viết như:

if(x == 2 || y == 4) 

Nhưng bạn thấy chúng tôi sẽ không nhận được nhiều lợi ích từ việc này, vì các phát biểu rất đơn giản và tối ưu hóa mã ở cấp độ này có thể không xứng đáng.

Bây giờ hãy xem xét một ví dụ như:

if(y == an_expensive_function() || x == 2) 

Đây giả an_expensive_function() là hoạt động rất tốn kém, nói đó là sự phức tạp giống như mũ, những chắc chắn nó làm cho tinh thần để đặt câu lệnh như:

if(x == 2 || y == an_expensive_function()) 

để thực hiện đoản mạch.

Nhà phát triển ứng dụng và nhúng hoặc bất kỳ nhà phát triển nào trong trường hợp đầu tiên có thể không xem xét tối ưu hóa ở mức độ chi tiết cao như vậy nếu điều này không mang lại nhiều lợi ích cho họ. Họ thậm chí có thể không xem xét nó nếu mọi thứ đang làm việc tốt cho họ. Vì vậy, với tư cách là nhà phát triển, chúng tôi cần kiểm tra, sẽ mất bao nhiêu thời gian để phân tích và tối ưu hóa mã ở cấp độ như vậy và chúng tôi nhận được bao nhiêu lợi ích từ việc này.

+0

Cảm ơn bạn đã giải thích, và ví dụ tuyệt vời để hiểu! Và dường như tất cả mọi người đang nói rằng không ai thực sự tốt giai điệu mã này cực đoan và điều quan trọng là để giải quyết các nút cổ chai đầu tiên, trước khi đi vào chi tiết như vậy. –

3

Chắc chắn.nếu có điều kiện bạn có dạng:

if (x() && y()) ... 

và y là tốn kém để tính toán, và x là giá rẻ và không thường xuyên, này sẽ cải thiện hiệu suất cục bộ của mã.

Vì vậy, bạn muốn biết:

  • là có điều kiện trong một phần biểu diễn nhạy cảm của chương trình (nếu không muốn nói, không có điểm trong việc tối ưu hóa nó, hãy viết cho rõ ràng)
  • chi phí tương đối của các thành phần tính toán biểu thức ngắn mạch
  • tính toán giá rẻ không thành công (đối với & &) hoặc thành công (cho ||) thường xuyên.

Trong trường hợp này, thường cần phải sắp xếp lại các phần tử biểu thức ngắn mạch.

+0

Cảm ơn bạn về ví dụ và giải thích ngắn gọn và đơn giản. Có vẻ như hầu hết mọi người nói trong các tình huống đơn giản như thế này là tốt nhất để sắp xếp lại chúng để cải thiện hiệu suất, trong các tình huống phức tạp chi phí phân tích nó sẽ lớn hơn nhiều so với hiệu suất nếu có bất kỳ cải tiến nào. Có vẻ như chìa khóa đang giải quyết các nút cổ chai của hiệu suất làm suy giảm! Cảm ơn bạn. –

+2

FWIW, khi tôi viết các điều kiện như vậy, tôi cố gắng đưa ra phán quyết về thứ tự như tôi viết, dựa trên những gì tôi biết. Một số có thể gọi tối ưu hóa sớm này; Tôi không cảm thấy bị kích thích là xứng đáng.Nếu điều kiện hiếm khi được thực hiện, nó sẽ không thành vấn đề nếu tôi nhận được lệnh sai. Nếu tình cờ có điều kiện hóa ra là trong con đường nóng, sau đó đến mức tôi ước tính đúng, thứ tự đã đúng và tôi không phải tìm nơi này với một hồ sơ và sửa nó sau; mã của tôi được điều chỉnh ổn định. Nếu tôi đã làm điều này ở khắp mọi nơi, mã của tôi thường chạy tốt hơn anyway. –

Các vấn đề liên quan