パフォーマンス、予期しない動作や読みやすさに関するベストパフォーマンス(C#の)
if(string.Empty.Equals(text))
と
if(text.Equals(string.Empty))
の間に違いはありますか?
パフォーマンス、予期しない動作や読みやすさに関するベストパフォーマンス(C#の)
if(string.Empty.Equals(text))
と
if(text.Equals(string.Empty))
の間に違いはありますか?
これらは同じ性能特性を持ちます。
text
がnull
の場合、2行目はNullReferenceException
です。
個人的に私は見つける:あなたのオプションのいずれかより
if(text == string.Empty)
より読みやすいです。
そしてそこにビルドされています。
if(string.IsNullOrEmpty(text))
と.NET 4.0のために:
if(string.IsNullOrWhitespace(text))
この場合には、性能差があってはなりません。それは "x == y"と "y == x"を比較するのと同じです。
私はif (text == string.Empty)
が最も読みやすい構文ですが、それは私です。
もちろん、if (string.IsNullOrEmpty(text)) { }
またはstring.IsNullOrWhiteSpace(text)
を使用することもできます。
予想外の動作としては、かなり単純な文字列比較です。私はあなたが予期しない行動をどのように得るのか想像できません。
私はIMOここで最も重要である、それはより読みやすいと思うように私は
if (string.IsNullOrEmpty(text))
{
}
使用することをお勧めします(実際には結果がnull
値に対して同じではないだろうが、あなたの第二のバージョンは投げるだろうこの特定のテストケースの例外)。
生成されたILに違いがあるかどうかはわかりませんが、いずれにしても、このようなマイクロ最適化(もしあれば...)によってアプリケーションが高速化することはありません。私は好奇心が強いよう
ちょうどそれをテストした:EDITは
private static void Main(string[] args)
{
Stopwatch z1 = new Stopwatch();
Stopwatch z2 = new Stopwatch();
Stopwatch z3 = new Stopwatch();
int count = 100000000;
string text = "myTest";
z1.Start();
for (int i = 0; i < count; i++)
{
int tmp = 0;
if (string.Empty.Equals(text))
{
tmp++;
}
}
z1.Stop();
z2.Start();
for (int i = 0; i < count; i++)
{
int tmp = 0;
if (text.Equals(string.Empty))
{
tmp++;
}
}
z2.Stop();
z3.Start();
for (int i = 0; i < count; i++)
{
int tmp = 0;
if (string.IsNullOrEmpty(text))
{
tmp++;
}
}
z3.Stop();
Console.WriteLine(string.Format("Method 1: {0}", z1.ElapsedMilliseconds));
Console.WriteLine(string.Format("Method 2: {0}", z2.ElapsedMilliseconds));
Console.WriteLine(string.Format("Method 3: {0}", z3.ElapsedMilliseconds));
Console.ReadKey();
}
マイクロ最適化をテストすることは、常にそれは見た目よりも複雑であるため、テストが関連していることを確認、しかし、ここではありませんいくつかの結果があります:
方法1と2は予想どおりですが、方法3では、あなたの選択をしてください;)
彼らは同じように動作します。予期しない動作については、text = nullの場合は2番目の文字がNullReferenceException
になる可能性があります。 if (!string.IsNullOrEmpty(text))
は、望ましくない予期しない動作やNREの可能性なしに、同じこと(同じパフォーマンス、同じ結果)を達成するために、より自然なようです。
これは同等です。
最初のケース:
IL_0000: nop
IL_0001: ldsfld string [mscorlib]System.String::Empty
IL_0006: ldarg.0
IL_0007: callvirt instance bool [mscorlib]System.String::Equals(string)
IL_000c: ldc.i4.0
IL_000d: ceq
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: brtrue.s <target>
第二の場合:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldsfld string [mscorlib]System.String::Empty
IL_0007: callvirt instance bool [mscorlib]System.String::Equals(string)
IL_000c: ldc.i4.0
IL_000d: ceq
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: brtrue.s <target>
テストショーが何をしましたか?それは本当に重要ですか? (あなたがソート/検索や類似している場合を除いて、最初にプロファイルする必要があり、答えがある場合を除いて)ボトルネックにならないことはほとんどありません。 –
'String.IsNullOrEmpty(text)'はどうでしょうか? – alex
'text.Length == 0' – ordag