Есть ли разница в производительности в Visual Basic при использовании функции IIf вместо оператора If?





Согласно этот парень, IIf может занимать до 6 раз больше, чем If / Then. YMMV.
... относительно того, почему это может длиться до 6 раз, говорится в вики:
Because IIf is a library function, it will always require the overhead of a function call, whereas a conditional operator will more likely produce inline code.
По сути, IIf является эквивалентом тернарного оператора в C++ / C#, поэтому он дает вам несколько хороших 1-строчных операторов типа if / else, если вы этого хотите. Вы также можете дать ему функцию для оценки, если хотите.
Кроме того, в этом случае удобочитаемость, вероятно, должна быть более предпочтительной, чем производительность. Даже если бы IIF был более эффективным, он просто менее читаем для целевой аудитории (я предполагаю, что если вы работаете в Visual Basic, вы хотите, чтобы другие программисты могли легко читать ваш код, что является самым большим благом VB ... и который, на мой взгляд, теряется с такими концепциями, как IIF).
Кроме того, «IIF - это функция, а IF - это часть синтаксиса языков» ... что означает для меня, что, действительно, If будет быстрее ... если бы ни для чего иное, кроме этого, оператор If можно было бы свести непосредственно к небольшому набору кодов операций, а не переходить в другое пространство в память для выполнения логики указанной функции. Разница, может быть, банальная, но стоит отметить.
IIf() запускает как истинный, так и ложный код. Для простых вещей, таких как числовое присвоение, это не имеет большого значения. Но для кода, который требует какой-либо обработки, вы тратите циклы на выполнение несоответствующего условия и, возможно, вызываете побочные эффекты.
Иллюстрация кода:
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
Выходы:
Foo!
Bar!
Кроме того, еще одна большая проблема с IIf заключается в том, что он фактически вызывает любые функции, которые находятся в arguments [1], поэтому, если у вас есть ситуация, подобная следующей:
string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty)
На самом деле это вызовет исключение, что не так, как большинство людей думают, что функция работает в первый раз, когда они ее видят. Это также может привести к очень сложным для исправления ошибкам в приложении.
[1] Функция IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx
Вот почему при замене старого IF у меня были проблемы с IIF, но IF сэкономил, добавив много строк кода.
У VB есть следующее утверждение If, к которому, я думаю, относится вопрос:
' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result, "Alternative")
Первый - это, по сути, тернарный условный оператор C#, а второй - его оператор объединения (возвращает result, если это не Nothing, и в этом случае возвращает "Alternative"). Таким образом, If заменил IIf, и последний устарел.
Как и в C#, условный оператор If в VB закорачивает, поэтому теперь вы можете безопасно написать следующее, что невозможно с помощью функции IIf:
Dim len = If(text Is Nothing, 0, text.Length)
Вы не ответили на вопрос о производительности, а также не упомянули о побочных эффектах IIf.
@jor Последний абзац моего ответа касается побочных эффектов. Когда одна из опций устарела, производительность не имеет особого значения. Как бы то ни было, собственный оператор If намного эффективнее, чем функция IIf.
Я что-то пропустил? все, что вы демонстрируете, это функция If ... Вы не демонстрируете, как синтаксис или использование различаются между IIf и If
@mmcrae Это правильно и нарочно: как я уже сказал, IIf устарел, поэтому нет смысла его обсуждать. Тем не менее, в моем последнем абзаце обсуждаются соответствующие различия. На самом деле это все, что вам нужно знать.
Я ценю, что вы хотите поддерживать хорошие стандарты и следить за тем, чтобы новички не применяли плохие методы, но у кого-то может быть совершенно законная проблема, из-за которой они захотят лучше понять разницу ... Например, поддержание устаревшего кода, застревание с какой-то другой инструмент, который его использует и т. д. И That's all you need to know, really не выглядит благоприятным для веб-сайта, посвященного обмену знаниями;)
@mmcrae О, я не хотел проявить снисходительность, я просто имел в виду, что внутренности IIf скучно тривиальны. Он просто содержит обычный оператор If, из которого следует, что последний фрагмент кода в моем ответе не запустится.
Кстати: избегайте этого типа вещей ... Dim name = IIf (myObject Is Nothing, "(не указано)", myObject.Name), так как вы получите исключение нулевой ссылки, если myObject имеет значение null. Обе ветви вычисляются, даже если будет возвращен результат только одной ветви. Лично я также стараюсь избегать всего, что написано на VB, но у меня не всегда есть выбор.
Лучше использовать If вместо IIf, чтобы правильно использовать механизм вывода типа (Option Infer On)
В этом примере ключевые слова распознаются как строка, когда я использую If:
Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
В противном случае он распознается как Объект:
Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
Я считаю, что основное различие между If и IIf:
Если (тест [логическое], оператор1, оператор2) это означает, что в соответствии с тестовым значением будет выполняться либо satement1, либо statement2 (будет выполнена только одна инструкция)
Dim obj = IIF (тест [логическое], оператор1, оператор2) это означает, что оба оператора будут выполнены, но в соответствии с тестовым значением один из них вернет значение в (obj).
поэтому, если один из операторов вызовет исключение, он все равно выбросит его в (IIf), но в (If) он выбросит его на всякий случай, если условие вернет свое значение.
Эти функции разные! Возможно, вам нужно использовать только оператор IF. IIF всегда будет медленнее, потому что он будет выполнять обе функции плюс стандартный оператор IF.
Если вам интересно, почему существует функция IIF, возможно, это будет объяснением:
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
Таким образом, после этого счетчик будет 2, но s будет только «ДА». Я знаю, что этот счетчик бесполезен, но иногда есть функции, которые вам понадобятся для запуска, не имеет значения, истинно или ложно IF, и просто присвойте значение из одного из них вашей переменной.
если вам нужны оба для запуска, вы должны явно вызвать их обоих, а затем выполнить стандартный If. Использование IIf() таким образом просто запутает людей, читающих ваш код.
Я не хотел, чтобы комментарий воспринимался как критика; Я просто указывал, что использовать его таким образом - не лучшая практика.
В моих эмпирических расчетах (10000000 циклов) я оценил, что IIf примерно в 12 раз медленнее!