Czy w języku Visual Basic występuje różnica w wydajności w przypadku używania IIf
funkcji zamiast If
instrukcji?
Czy w języku Visual Basic występuje różnica w wydajności w przypadku używania IIf
funkcji zamiast If
instrukcji?
Odpowiedzi:
VB ma następujące If
stwierdzenie, do którego, jak sądzę, odnosi się pytanie:
' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result, "Alternative")
Pierwszy to w zasadzie trójskładnikowy operator warunkowy w języku C #, a drugi to jego operator łączenia (zwrot, result
chyba że jest Nothing
, w takim przypadku powrót "Alternative"
). If
w ten sposób zastąpił, IIf
a ten ostatni jest przestarzały.
Podobnie jak w C #, warunkowe If
zwarcia operatora VB , więc możesz teraz bezpiecznie napisać co następuje, co nie jest możliwe przy użyciu IIf
funkcji:
Dim len = If(text Is Nothing, 0, text.Length)
If
jest znacznie wydajniejszy niż IIf
funkcja.
That's all you need to know, really
nie brzmi jak sprzyjająca postawa dla strony poświęconej dzieleniu się wiedzą;)
IIf()
uruchamia zarówno kod prawda, jak i fałsz. W przypadku prostych rzeczy, takich jak przypisanie numeryczne, nie jest to wielka sprawa. Ale w przypadku kodu, który wymaga jakiegokolwiek przetwarzania, marnujesz cykle uruchamiające niezgodny warunek i prawdopodobnie powodując efekty uboczne.
Ilustracja kodu:
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
Wyjścia:
Foo!
Bar!
Kolejnym dużym problemem związanym z IIf jest to, że faktycznie wywoła on wszystkie funkcje, które znajdują się w argumentach [1], więc jeśli masz sytuację podobną do poniższej:
string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty)
W rzeczywistości zgłosi wyjątek, co nie jest sposobem, w jaki większość ludzi myśli, że funkcja działa, gdy ją widzą po raz pierwszy. Może to również prowadzić do bardzo trudnych do naprawienia błędów w aplikacji.
[1] Funkcja IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx
Lepiej używać If zamiast IIf, aby poprawnie używać mechanizmu wnioskowania o typie (Option Infer On)
W tym przykładzie słowa kluczowe są rozpoznawane jako ciąg, gdy używam If:
Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
W przeciwnym razie jest rozpoznawany jako obiekt:
Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
Według tego gościa , IIf może trwać do 6 razy dłużej niż If / Then. YMMV.
Ponadto w tym przypadku czytelność powinna być prawdopodobnie bardziej preferowana niż wydajność. Nawet jeśli IIF byłby bardziej wydajny, jest po prostu mniej czytelny dla docelowych odbiorców (zakładam, że jeśli pracujesz w Visual Basic, chcesz, aby inni programiści mogli łatwo czytać twój kod, co jest największym dobrodziejstwem VB ... i co moim zdaniem jest stracone w przypadku pojęć takich jak IIF).
Ponadto „IIF jest funkcją, w przeciwieństwie do funkcji IF będącej częścią składni języków” ... co oznacza dla mnie, że rzeczywiście, jeśli byłoby szybsze ... gdyby nie nic innego, jak tylko to, że instrukcja If może być bezpośrednio sprowadzona do małego zestawu rozkazów, zamiast konieczności przechodzenia do innego miejsca w pamięci, aby wykonać logikę znalezioną we wspomnianej funkcji. Może to banalna różnica, ale warto ją zauważyć.
Uważam, że główna różnica między If i IIf to:
Jeśli (test [boolean], instrukcja1, instrukcja2) oznacza to, że zgodnie z wartością testu zostanie wykonana satement1 lub instrukcja2 (zostanie wykonana tylko jedna instrukcja)
Dim obj = IIF (test [boolean], instrukcja1, instrukcja2) oznacza to, że obie instrukcje zostaną wykonane, ale zgodnie z wartością testową jedna z nich zwróci wartość do (obj).
więc jeśli jedna z instrukcji zgłosi wyjątek, i tak wyrzuci ją w (IIf), ale w (If) wyrzuci ją na wypadek, gdyby warunek zwrócił jego wartość.
... dlaczego może to potrwać tak długo, jak 6x, powiedz wiki:
Ponieważ IIf jest funkcją biblioteczną, zawsze będzie wymagać narzutu wywołania funkcji, podczas gdy operator warunkowy z większym prawdopodobieństwem utworzy kod wbudowany.
Zasadniczo IIf jest odpowiednikiem operatora trójskładnikowego w C ++ / C #, więc daje ci kilka ładnych instrukcji typu if / else, jeśli chcesz. Możesz również nadać mu funkcję oceny, jeśli chcesz.
Te funkcje są różne! Być może wystarczy użyć instrukcji IF. Funkcja IIF zawsze będzie wolniejsza, ponieważ będzie wykonywać obie funkcje, a ponadto wykona standardową instrukcję IF.
Jeśli zastanawiasz się, dlaczego istnieje funkcja IIF, może to będzie wyjaśnienie:
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
Tak więc licznik po tym będzie wynosił 2, ale s będzie tylko „TAK”. Wiem, że ten licznik jest bezużyteczny, ale czasami są funkcje, które będziesz potrzebować do uruchomienia obu, nie ma znaczenia, czy to prawda, czy fałsz, i po prostu przypisz wartość jednej z nich do swojej zmiennej.
IIf()
w ten sposób zmyli ludzi czytających Twój kod.
IIf
.