Разница в производительности между IIf () и If

98

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

Брайан Рот
источник

Ответы:

140

IfЯ думаю, что у VB есть следующее утверждение, к которому относится вопрос:

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

Первый - это, по сути, тернарный условный оператор C #, а второй - его оператор объединения (return, resultесли он не используется Nothing, и в этом случае return "Alternative"). Ifбыл заменен, IIfи последний устарел.

Как и в C #, условный Ifоператор VB сокращает работу, поэтому теперь вы можете безопасно написать следующее, что невозможно с помощью IIfфункции:

Dim len = If(text Is Nothing, 0, text.Length)
Конрад Рудольф
источник
3
Вы не ответили на вопрос о производительности, а также не упомянули о побочных эффектах IIf.
jor
2
@jor Последний абзац моего ответа касается побочных эффектов. Когда одна из опций устарела, производительность не имеет особого значения. Как бы то ни было, нативный оператор Ifнамного эффективнее, чем IIfфункция.
Конрад Рудольф
2
@mmcrae Это правильно и нарочно: как я уже сказал, IIf устарел, поэтому нет смысла его обсуждать. Тем не менее, в моем последнем абзаце обсуждаются соответствующие различия. На самом деле это все, что вам нужно знать.
Конрад Рудольф
2
Я ценю, что вы хотите поддерживать хорошие стандарты и гарантировать, что новички не усваивают плохие методы, но у кого-то может быть совершенно законная проблема, из-за которой они захотят лучше понять разницу ... Например, поддержание устаревшего кода, застревание с какой-то другой инструмент, который его использует, и т. д. И That's all you need to know, reallyэто не похоже на благоприятное отношение к веб-сайту, посвященному обмену знаниями;)
Дон Чидл,
1
@mmcrae О, я не хотел быть снисходительным, я просто имел в виду, что внутренности IIf до скучно тривиальны. Он просто содержит обычный оператор If, из которого следует, что последний фрагмент кода в моем ответе не запустится.
Конрад Рудольф
65

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!
Thomas G. Mayfield
источник
13

Кроме того, еще одна большая проблема с 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

rjzii
источник
Вот почему, если я пришел на замену старой IIF, у меня были проблемы с IIF, но IF сэкономил, добавив много строк кода.
NiL
7

Лучше использовать If вместо IIf, чтобы правильно использовать механизм вывода типа (Option Infer On)

В этом примере ключевые слова распознаются как строка, когда я использую If:

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

В противном случае он распознается как Объект:

Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
Ларри
источник
6

По словам этого парня , IIf может занимать до 6 раз больше, чем If / Then. YMMV.

Грег Херлман
источник
1
В моих эмпирических расчетах (10000000 циклов) я оценил, что IIf примерно в 12 раз медленнее!
Phantômaxx 01
6

Кроме того, в этом случае удобочитаемость, вероятно, должна быть более предпочтительной, чем производительность. Даже если бы IIF был более эффективным, он просто менее читаем для целевой аудитории (я предполагаю, что если вы работаете с Visual Basic, вы хотите, чтобы другие программисты могли легко читать ваш код, что является самым большим благом VB ... и который, на мой взгляд, теряется с такими концепциями, как IIF).

Кроме того, «IIF - это функция, в отличие от IF, являющейся частью синтаксиса языков» ... что подразумевает для меня, что, действительно, If будет быстрее ... если бы ни для чего иное, кроме этого, оператор If может быть сокращен напрямую к небольшому набору кодов операций, вместо того чтобы переходить в другое место в памяти для выполнения логики, найденной в указанной функции. Разница, может быть, банальная, но стоит отметить.

Эдгар Верона
источник
6

Я считаю, что основное различие между If и IIf:

  • Если (test [boolean], statement1, statement2), это означает, что в соответствии с тестовым значением будет выполнено либо satement1, либо statement2 (будет выполняться только один оператор)

  • Dim obj = IIF (test [boolean], statement1, statement2) означает, что оба оператора будут выполняться, но в соответствии с тестовым значением один из них вернет значение в (obj).

поэтому, если один из операторов вызовет исключение, он все равно выбросит его в (IIf), но в (If) он выбросит его на всякий случай, если условие вернет свое значение.

какой-то парень
источник
5

... относительно того, почему это может занять до 6 раз, говорится в вики:

Поскольку IIf - это библиотечная функция, она всегда требует дополнительных затрат на вызов функции, тогда как условный оператор, скорее всего, создаст встроенный код.

По сути, IIf является эквивалентом тернарного оператора в C ++ / C #, поэтому он дает вам несколько хороших 1-строчных операторов типа if / else, если вы этого хотите. Вы также можете дать ему функцию для оценки, если хотите.

Дилли-О
источник
1

Эти функции разные! Возможно, вам нужно использовать только оператор 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()просто запутает людей, читающих ваш код.
Spivonious
Я не хотел, чтобы комментарий воспринимался как критика; Я просто указал на то, что использовать его таким образом - не лучшая практика.
Spivonious