IIf()とIfのパフォーマンスの違い


回答:


140

VBには次のようなIf記述があります。

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

1つ目は基本的にC#の3項条件演算子であり、2つ目は合体演算子です(resultそれ以外のNothing場合はreturn、その場合はreturn "Alternative")。Ifこのように置き換えられIIf、後者は廃止されました。

C#と同様に、VBの条件If演算子は短絡しているため、次のコードを安全に記述できます。これは、IIf関数を使用して行うことはできません。

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

2
パフォーマンスに関する質問には答えず、の副作用についても触れませんでしたIIf
ジョー

2
@jor私の回答の最後の段落は、副作用についてです。オプションの1つが廃止された場合、パフォーマンスは実際には関係ありません。それだけの価値があるのですIfが、ネイティブ演算子はIIf関数よりもはるかに効率的です。
Konrad Rudolph

2
@mmcrae正解であり、意図的です。すでに述べたように、IIfは廃止されているため、それを議論する意味はほとんどありません。とはいえ、私の最後の段落では、関連する違いについて説明しています。本当に知っておくべきことはこれだけです。
Konrad Rudolph

2
良い基準をサポートし、初心者が悪い習慣を身につけないようにしてほしいと思っていますが、誰かが完全に正当な問題を抱えているため、違いをよりよく理解したいと思っているかもしれません...それを使用する他のいくつかのツールなど。That's all you need to know, really知識の共有に専念するWebサイトの助長的な態度のようには聞こえません;)
Don Cheadle

1
@mmcraeああ、私は非難するつもりはありませんでした、私は本当にIIfの内部が退屈につまらないことを意味しただけです。これには、従来のIfステートメントが含まれているだけです。これは、私の回答の最後のコードが実行されないことを意味します。
Konrad Rudolph

65

IIf()trueとfalseの両方のコードを実行します。数値の割り当てなどの単純なことについては、これは大した問題ではありません。しかし、なんらかの処理を必要とするコードでは、一致しない条件を実行するサイクルが無駄になり、副作用が発生する可能性があります。

コード図:

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!

13

また、IIfのもう1つの大きな問題は、引数[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


これが、古いIIFを置き換える場合、IIFに問題があったがIFが多くのコード行を追加することを節約した理由です。
NiL 2014

7

型推論メカニズムを正しく使用するためにIIfの代わりにIfを使用する(Option Infer On)

この例では、Ifを使用すると、キーワードが文字列として認識されます。

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

それ以外の場合は、オブジェクトとして認識されます。

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


6

その上、この場合は、おそらくパフォーマンスよりも可読性の方がはるかに優先されるはずです。IIFの方が効率的だったとしても、対象ユーザーにとってはあまり読みやすくありません(Visual Basicで作業している場合、他のプログラマーがコードを簡単に読み取れるようにしたいと思います。これはVBの最大の恩恵です...私の意見ではIIFのような概念で失われています)。

また、「IIFは関数であり、IFは言語の構文の一部である」 ...これは、実際には、Ifの方が高速であることを意味します...それ以外の場合は、Ifステートメントを直接煮詰めることができます上記の関数にあるロジックを実行するためにメモリ内の別のスペースに移動する必要はなく、オペコードの小さなセットに。それはおそらく少しの違いですが、注目に値します。


6

IfとIIfの主な違いは次のとおりです。

  • if(test [boolean]、statement1、statement2)は、テスト値に従ってsatement1またはstatement2のいずれかが実行されることを意味します(1つのステートメントのみが実行されます)

  • Dim obj = IIF(test [boolean]、statement1、statement2)これは、両方のステートメントは実行されますが、テスト値に従って、それらの1つが(obj)に値を返すことを意味します。

したがって、ステートメントの1つが例外をスローする場合は、とにかく(IIf)でスローしますが、(If)の場合は、条件がその値を返す場合に備えてスローします。


5

...なぜ6倍もかかるのかについては、wikiを引用してください:

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は "YES"のみになります。私はこのカウンターが役に立たないことを知っていますが、IFがtrueかfalseかを問わず、両方を実行するために必要な関数が時々あり、それらの1つから変数に値を割り当てるだけです。


両方を実行する必要がある場合は、両方を明示的に呼び出してから、標準のIfを実行する必要があります。IIf()このように使用すると、コードを読んでいる人々を混乱させるだけです。
Spivonious

私はそれを知っていますが、問題はこれら2つの違いです。
ティトールは、

コメントが批判として出くわすことを意味しなかった。このように使用することは良い習慣ではないことを指摘しました。
16年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.