Biên tập:
Đã thêm một ví dụ có thể được thực hiện với câu lệnh if-other nhưng không phải là toán tử điều kiện.
Trước khi trả lời, xin vui lòng xem [ Cái nào nhanh hơn? ] trên blog của ông Lippert. Và tôi nghĩ câu trả lời của ông Ersönmez là câu trả lời đúng nhất ở đây.
Tôi đang cố gắng đề cập đến một cái gì đó chúng ta nên ghi nhớ với một ngôn ngữ lập trình cấp cao.
Trước hết, tôi chưa bao giờ nghe nói rằng toán tử có điều kiện được cho là nhanh hơn hoặc hiệu suất tương đương với câu lệnh if- other trong C♯ .
Lý do rất đơn giản là nếu không có hoạt động với câu lệnh if-other:
if (i > 0)
{
value += 2;
}
else
{
}
Yêu cầu của toán tử có điều kiện là phải có một giá trị với một trong hai bên và trong C♯, nó cũng yêu cầu cả hai bên :
có cùng loại. Điều này chỉ làm cho nó khác với tuyên bố if-other. Do đó, câu hỏi của bạn trở thành một câu hỏi hỏi làm thế nào hướng dẫn của mã máy được tạo ra sao cho sự khác biệt về hiệu suất.
Với toán tử có điều kiện, về mặt ngữ nghĩa là:
Bất cứ biểu thức nào được đánh giá, đều có giá trị.
Nhưng với câu lệnh if-other:
Nếu biểu thức được đánh giá là đúng, hãy làm một cái gì đó; nếu không, hãy làm một việc khác
Một giá trị không nhất thiết liên quan đến câu lệnh if-other. Giả định của bạn chỉ có thể với tối ưu hóa.
Một ví dụ khác để chứng minh sự khác biệt giữa chúng sẽ như sau:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
Tuy nhiên, đoạn mã trên biên dịch, thay thế câu lệnh if-other bằng toán tử có điều kiện sẽ không biên dịch:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
Toán tử điều kiện và các câu lệnh if-other có khái niệm giống nhau khi bạn làm điều tương tự, nó thậm chí có thể nhanh hơn với toán tử điều kiện trong C , vì C gần với việc lắp ráp nền tảng hơn.
Đối với mã ban đầu bạn cung cấp, toán tử điều kiện được sử dụng trong vòng lặp foreach, điều này sẽ làm mọi thứ rối tung lên để thấy sự khác biệt giữa chúng. Vì vậy, tôi đang đề xuất mã sau đây:
public static class TestClass {
public static void TestConditionalOperator(int i) {
long value=0;
value+=i>0?2:3;
}
public static void TestIfElse(int i) {
long value=0;
if(i>0) {
value+=2;
}
else {
value+=3;
}
}
public static void TestMethod() {
TestConditionalOperator(0);
TestIfElse(0);
}
}
và sau đây là hai phiên bản IL được tối ưu hóa và không. Vì chúng dài, tôi đang sử dụng một hình ảnh để hiển thị, phía bên tay phải là hình được tối ưu hóa:
(Nhấn để xem hình với đầy đủ kích thước.)
Trong cả hai phiên bản mã, IL của toán tử điều kiện có vẻ ngắn hơn câu lệnh if-other và vẫn còn nghi ngờ về mã máy cuối cùng được tạo. Sau đây là hướng dẫn của cả hai phương thức và hình ảnh trước đây không được tối ưu hóa, hình ảnh sau là hình ảnh được tối ưu hóa:
Trong phần sau, khối màu vàng là mã chỉ được thực thi nếu i<=0
và khối màu xanh là khi i>0
. Trong cả hai phiên bản hướng dẫn, câu lệnh if-other ngắn hơn.
Lưu ý rằng, đối với các hướng dẫn khác nhau, [ CPI ] không nhất thiết phải giống nhau. Theo logic, đối với hướng dẫn giống hệt nhau, nhiều hướng dẫn hơn chi phí chu kỳ dài hơn. Nhưng nếu thời gian tìm nạp lệnh và ống / bộ đệm cũng được tính đến, thì tổng thời gian thực hiện thực sự phụ thuộc vào bộ xử lý. Bộ xử lý cũng có thể dự đoán các nhánh.
Bộ xử lý hiện đại thậm chí còn có nhiều lõi hơn, mọi thứ có thể phức tạp hơn với điều đó. Nếu bạn là người dùng bộ xử lý Intel, bạn có thể muốn xem [ Hướng dẫn tham khảo tối ưu hóa kiến trúc Intel® 64 và IA-32 ].
Tôi không biết nếu có CLR được triển khai bằng phần cứng, nhưng nếu có, bạn có thể nhanh hơn với toán tử có điều kiện vì IL rõ ràng là ít hơn.
Lưu ý: Tất cả các mã máy là x86.
DateTime
để đo lường hiệu suất. Sử dụngStopwatch
. Tiếp theo, thời gian khá dài - đó là một thời gian rất ngắn để đo lường.