Visual Basicで、ステートメントIIf
の代わりに関数を使用した場合、パフォーマンスに違いはありますか?If
9 に答える
VBにはIf
、質問が参照する次のステートメントがあります。
' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result, "Alternative")
1 つ目は基本的に C# の 3 項条件演算子であり、2 つ目は合体演算子 ( returnresult
でないNothing
場合は return 、その場合は return "Alternative"
) です。If
が置き換えられIIf
、後者は廃止されました。
C# と同様に、VB の条件If
演算子は短絡するため、次のように安全に記述できますが、IIf
関数を使用することはできません。
Dim len = If(text Is Nothing, 0, text.Length)
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!
また、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はIf/Thenの最大6倍の時間がかかる可能性があります。YMMV。
型推論メカニズムを正しく使用するには、IIf の代わりに If を使用することをお勧めします (Option Infer On)。
この例では、 If を使用すると Keywords が文字列として認識されます。
Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
それ以外の場合は、 Object として認識されます:
Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
それに加えて、この場合、おそらくパフォーマンスよりも可読性の方が優先されるはずです。IIF の方が効率的であったとしても、ターゲット ユーザーにとって読みにくいだけです (Visual Basic で作業している場合は、他のプログラマーが自分のコードを簡単に読めるようにしたいと思うでしょう。これは VB の最大の利点です...そして私の意見では、IIF のような概念では失われます)。
また、「IIFは関数であり、IFは言語の構文の一部であるのに対して」 ...これは、実際、Ifの方が高速であることを意味します...それ以外の理由がない場合、Ifステートメントを直接煮詰めることができます上記の関数で見つかったロジックを実行するためにメモリ内の別のスペースに移動する必要がなく、小さなオペコードのセットに。おそらく些細な違いですが、注目に値します。
If と IIf の主な違いは次のとおりだと思います。
If(test [boolean], statement1, statement2) は、テスト値に従って、satement1 または statement2 のいずれかが実行されることを意味します (1 つのステートメントのみが実行されます)。
Dim obj = IIF(test [boolean] , statement1, statement2) これは、両方のステートメントが実行されることを意味しますが、テスト値に従って、そのうちの 1 つが (obj) に値を返します。
そのため、ステートメントの 1 つが例外をスローする場合は、(IIf) で例外をスローしますが、(If) では、条件が値を返す場合に備えて例外をスローします。
...なぜ 6 倍もの時間がかかるのかについては、wiki を引用してください。
IIf はライブラリ関数であるため、常に関数呼び出しのオーバーヘッドが必要になりますが、条件演算子はインライン コードを生成する可能性が高くなります。
基本的に、IIf は C++/C# の三項演算子に相当するため、必要に応じて 1 行の if/else 型ステートメントを作成できます。必要に応じて、評価する関数を指定することもできます。