Hiệu suất khác biệt giữa IIf () và If


Câu trả lời:


140

VB có câu sau Ifmà câu hỏi đề cập đến, tôi nghĩ:

' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result, "Alternative")

Đầu tiên về cơ bản là toán tử điều kiện bậc ba của C # và thứ hai là toán tử liên kết của nó (trả về resulttrừ khi nó Nothing, trong trường hợp đó trả về "Alternative"). Ifdo đó đã thay thế IIfvà sau này là lỗi thời.

Giống như trong C #, Ifngắn mạch toán tử có điều kiện của VB , vì vậy bây giờ bạn có thể viết một cách an toàn như sau, điều này không thể thực hiện được bằng cách sử dụng IIfhàm:

Dim len = If(text Is Nothing, 0, text.Length)

2
Bạn đã không trả lời câu hỏi về hiệu suất và cũng không đề cập đến tác dụng phụ của IIf.
Jor

2
@jor Đoạn cuối cùng của câu trả lời của tôi là về các tác dụng phụ. Hiệu suất không thực sự phù hợp khi một trong các tùy chọn đã lỗi thời. Đối với những gì nó đáng giá, toán tử gốc Ifhiệu quả hơn IIfhàm cho đến nay.
Konrad Rudolph

2
@mmcrae Điều đó đúng và đúng mục đích: như tôi đã nói, IIf đã lỗi thời, vì vậy có rất ít ý nghĩa khi thảo luận về nó. Điều đó nói rằng, đoạn cuối của tôi thảo luận về sự khác biệt có liên quan. Đó là tất cả những gì bạn cần biết, thực sự.
Konrad Rudolph

2
Tôi đánh giá cao việc bạn muốn hỗ trợ các tiêu chuẩn tốt và đảm bảo người mới không tiếp thu các phương pháp xấu, nhưng ai đó có thể gặp vấn đề hoàn toàn hợp pháp khiến họ muốn hiểu rõ hơn sự khác biệt ... Chẳng hạn như duy trì mã cũ, bị mắc kẹt với một số công cụ khác mà sử dụng nó, vv Và That's all you need to know, reallykhông âm thanh như một thái độ thuận lợi cho một trang web dành cho việc chia sẻ kiến thức;)
Don Cheadle

1
@mmcrae Ồ, tôi không có ý chê bai, tôi chỉ thực sự muốn nói rằng nội bộ của IIf quá tầm thường. Nó chỉ đơn giản chứa một câu lệnh If thông thường, ngụ ý rằng đoạn mã cuối cùng trong câu trả lời của tôi sẽ không chạy.
Konrad Rudolph

65

IIf()chạy cả mã đúng và sai. Đối với những thứ đơn giản như gán số, đây không phải là vấn đề lớn. Nhưng đối với mã yêu cầu bất kỳ loại xử lý nào, bạn đang lãng phí các chu kỳ chạy điều kiện không phù hợp và có thể gây ra các tác dụng phụ.

Mã minh họa:

Module Module1
    Sub Main()
        Dim test As Boolean = False
        Dim result As String = IIf(test, Foo(), Bar())
    End Sub

    Public Function Foo() As String
        Console.WriteLine("Foo!")
        Return "Foo"
    End Function

    Public Function Bar() As String
        Console.WriteLine("Bar!")
        Return "Bar"
    End Function
End Module

Kết quả đầu ra:

Foo!
Bar!

13

Ngoài ra, một vấn đề lớn khác với IIf là nó sẽ thực sự gọi bất kỳ hàm nào có trong các đối số [1], vì vậy nếu bạn gặp trường hợp như sau:

string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty)

Nó thực sự sẽ ném ra một ngoại lệ, đây không phải là cách mà hầu hết mọi người nghĩ rằng hàm hoạt động ngay lần đầu tiên họ nhìn thấy nó. Điều này cũng có thể dẫn đến một số lỗi rất khó sửa trong một ứng dụng.

[1] Hàm IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx


Đây là lý do tại sao nếu đến để thay thế IIF cũ, tôi đã từng gặp vấn đề với IIF nhưng IF đã lưu thêm nhiều dòng mã.
NiL

7

Sử dụng tốt hơn If thay vì IIf để sử dụng cơ chế suy luận kiểu chính xác (Tùy chọn Infer On)

Trong ví dụ này, Từ khóa được nhận dạng là một chuỗi khi tôi sử dụng Nếu:

Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)

Nếu không, nó được công nhận là một Đối tượng:

Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)

6

Theo anh chàng này , IIf có thể mất tới 6 lần miễn là If / Then. YMMV.


1
Trong các tính toán thực nghiệm của tôi (10000000 chu kỳ), tôi đánh giá IIf chậm hơn khoảng 12 lần!
Phantômaxx

6

Trên hết, khả năng đọc có lẽ nên được ưu tiên cao hơn hiệu suất trong trường hợp này. Ngay cả khi IIF hiệu quả hơn, nó chỉ đơn giản là ít dễ đọc đối với đối tượng mục tiêu (Tôi giả sử nếu bạn đang làm việc trong Visual Basic, bạn muốn các lập trình viên khác có thể đọc mã của bạn dễ dàng, đó là lợi ích lớn nhất của VB ... và mà bị mất với các khái niệm như IIF theo ý kiến ​​của tôi).

Ngoài ra, "IIF là một hàm, so với IF là một phần của cú pháp ngôn ngữ" ... điều này ngụ ý với tôi rằng, thực sự, If sẽ nhanh hơn ... nếu không có gì khác hơn là câu lệnh If có thể được rút gọn trực tiếp đến một tập hợp nhỏ các mã quang thay vì phải đi đến một không gian khác trong bộ nhớ để thực hiện logic được tìm thấy trong chức năng đã nói. Đó là một sự khác biệt nhỏ, có lẽ, nhưng đáng chú ý.


6

Tôi tin rằng sự khác biệt chính giữa If và IIf là:

  • Nếu (test [boolean], statement1, statement2) thì có nghĩa là theo giá trị thử nghiệm, satement1 hoặc statement2 sẽ được thực thi (chỉ một câu lệnh sẽ thực thi)

  • Dim obj = IIF (test [boolean], statement1, statement2) có nghĩa là cả hai câu lệnh sẽ thực thi nhưng theo giá trị thử nghiệm, một trong số chúng sẽ trả về giá trị là (obj).

vì vậy nếu một trong các câu lệnh sẽ ném một ngoại lệ, nó sẽ ném nó vào (IIf) nhưng trong (If), nó sẽ ném nó chỉ trong trường hợp điều kiện sẽ trả về giá trị của nó.


5

... về lý do tại sao có thể mất tới 6 lần, hãy trả lời wiki:

Bởi vì IIf là một hàm thư viện, nó sẽ luôn yêu cầu chi phí của một lệnh gọi hàm, trong khi toán tử có điều kiện sẽ tạo ra mã nội tuyến nhiều hơn.

Về cơ bản, IIf tương đương với toán tử bậc ba trong C ++ / C #, vì vậy nó cung cấp cho bạn một số câu lệnh kiểu if / else 1 dòng tuyệt vời nếu bạn muốn. Bạn cũng có thể cung cấp cho nó một chức năng để đánh giá nếu bạn muốn.


1

Các chức năng đó khác nhau! Có lẽ bạn chỉ cần sử dụng câu lệnh IF. IIF sẽ luôn chậm hơn, vì nó sẽ thực hiện cả hai chức năng cộng với nó sẽ thực hiện câu lệnh IF tiêu chuẩn.

Nếu bạn đang tự hỏi tại sao có chức năng IIF, có thể đây sẽ là lời giải thích:

Sub main()
    counter = 0
    bln = True
    s = iif(bln, f1, f2)
End Sub

Function f1 As String
    counter = counter + 1
    Return "YES"
End Function

Function f2 As String
    counter = counter + 1
    Return "NO"
End Function

Vì vậy, bộ đếm sẽ là 2 sau này, nhưng s sẽ chỉ là "CÓ". Tôi biết công cụ bộ đếm này là vô dụng, nhưng đôi khi có những hàm mà bạn sẽ cần cả hai để chạy, không quan trọng IF đúng hay sai và chỉ cần gán giá trị từ một trong số chúng cho biến của bạn.


nếu bạn cần cả hai để chạy, bạn nên gọi rõ ràng cả hai và sau đó thực hiện một If chuẩn. Sử dụng IIf()theo cách này sẽ chỉ gây nhầm lẫn cho mọi người khi đọc mã của bạn.
Spivonious

Tôi biết điều đó, nhưng câu hỏi là về sự khác biệt giữa hai điều đó.
titol

Tôi không có ý coi nhận xét đó là một lời chỉ trích; Tôi chỉ chỉ ra rằng sử dụng nó theo cách này không phải là một cách thực hành tốt.
Spivonious
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.