22

文字列を比較する方法はいくつかあります。ある方法を別の方法で行うことにより、パフォーマンスが向上しますか?

私は常に次のように文字列を比較することを選択してきました。

string name = "Bob Wazowski";
if (name.CompareTo("Jill Yearsley") == 0) {
    // whatever...
}

しかし、これを行っている人はほとんどいません。どちらかといえば、単純な == 比較を行っている人が多く見られます。これは、私の知る限り、文字列を比較する最悪の方法です。私が間違っている?

また、LINQ クエリ内で文字列を比較する方法に違いはありますか? たとえば、私は次のことをするのが好きです。

var results = from names in ctx.Names
              where names.FirstName.CompareTo("Bob Wazowski") == 0
              select names;

しかし、繰り返しになりますが、LINQ クエリでこのような文字列比較を行っている人はほとんどいません。

4

10 に答える 10

28

リフレクターによると

"Hello" == "World"

と同じです

String.Equals("Hello", "World");

基本的に、それらが同じ参照オブジェクトであるかどうか、どちらかが null の場合、一方が null で他方がそうでない場合は自動的に false になるかどうかを判断し、安全でないループで各文字を比較します。そのため、通常は大したことではない文化的ルールはまったく気にしません。

"Hello".CompareTo("World") == 0

と同じです

CultureInfo.CurrentCulture.CompareInfo.Compare("Hello", "World", CompareOptions.None);

これは基本的に、機能に関しては逆です。文化、エンコーディング、およびコンテキスト内の文字列を含むその他すべてが考慮されます。

したがって、String.CompareTo は等値演算子よりも数桁遅いと思います。

LINQ に関しては、LINQ-to-SQL を使用しているかどうかは問題ではありません。どちらも同じ SQL を生成するためです。

var results = from names in ctx.Names
          where names.FirstName.CompareTo("Bob Wazowski") == 0
          select names;

SELECT [name fields]
FROM [Names] AS [t0]
WHERE [t0].FirstName = @p0

したがって、コードが読みにくくなり、おそらく式の解析が増えることを除いて、LINQ-to-SQL では何も得られません。標準の配列に LINQ を使用しているだけの場合は、上記のルールが適用されます。

于 2009-05-13T17:45:50.407 に答える
16

私の意見では、常に最も明確な方法を使用する必要があります==

これは直接理解できます。「Hello」が「World」に等しい場合、何かを行います。

if ("Hello" == "World")
    // ...

内部String::Equals的には、この目的のために明示的に存在する が呼び出されます - 2 つの文字列が等しいかどうかを比較します。(これはポインタや参照などとは関係ありません。)

これはすぐにはわかりません - なぜゼロと比較するのですか?

if ("Hello".CompareTo("World") == 0)

.CompareTo は、等価性をチェックするためだけに設計されたものではありません (これには == があります) - 2 つの文字列を比較します。ソートで .CompareTo を使用して、ある文字列が別の文字列よりも「大きい」かどうかを判断します。等しい文字列に対してゼロを生成するため、等しいことを確認できますが、それは概念の目的ではありません。

したがって、等価性のチェック (IEquatable、演算子 ==) と比較 (IComparable) にはさまざまなメソッドとインターフェイスがあります。

ここでは、Linq は通常の C# と異なる動作をしません。

于 2009-05-13T16:48:24.697 に答える
8

Jeff のThe Best Code is No Code at Allを読んでください。foo.CompareTo(bar) == 0: ひどい視覚的な混乱。多くのスペースを取り、興味深い意味を伝えません。実際、それは実際の問題から注意をそらす多くの無関係なものを強調しています.

この長いバリアントを使用する明確な理由がない場合は、使用しないでください。

パフォーマンスに関しては、この単純なケースでは問題になりません。等値演算子の==パフォーマンスが実際に よりも悪い場合はCompareTo、Microsoft にバグ レポートを提出してください。これは起こってはなりません。

于 2009-05-13T16:50:10.683 に答える
5

さて、MSDNは、実行する必要のあるタスクに応じて比較関数を使用する必要があると述べています。

CompareToメソッドは、主に並べ替えまたはアルファベット順の操作で使用するために設計されました。メソッド呼び出しの主な目的が2つの文字列が同等であるかどうかを判断することである場合は、使用しないでください。2つの文字列が同等であるかどうかを判断するには、Equalsメソッドを呼び出します。

したがって、並べ替えではなく、retrun値が重要でない場合は、次を使用する必要があります。

first.Equals(second) または、比較が文化固有の場合、たとえばドイツ語などの言語の場合:

String.Equals(first, second, StringComparison.CurrentCulture)

これらのリンクを見てください:

方法:文字列を比較する(C#プログラミングガイド)

String.CompareToメソッド(オブジェクト)

于 2013-01-14T06:55:01.867 に答える
2

最近、ストリングをトリミングする最速の方法に関してかなり似たような質問がありましたが、基本的にはそれらを比較するさまざまな方法をベンチマークしていました。

この投稿でベンチマークを確認できます。

于 2009-05-13T16:41:23.897 に答える
1

文字列比較よりも少し一般的ですが、それでも非常に興味深い記事Comparing Values for Equality in .NET: Identity and Equivalenceがあります。

于 2009-05-13T16:58:09.033 に答える
1

等値演算子の実際のパフォーマンスがCompareTo- より悪い場合、Microsoft は等値演算子呼び出しの実装を作成しませんCompareToか?

等しいかどうかをテストするには、等値演算子を使用するだけです。

于 2009-05-13T17:19:19.373 に答える
0

私は通常、StringComparison パラメーターを受け取るオーバーロードと共に String.Compare を使用します。これは、比較で大文字と小文字およびカルチャを区別するかどうかを完全に明示できるためです。これには .NET 2.0 以降が必要です。

カルチャに依存しない比較の場合、最も高速なのは StringComparison.Ordinal (大文字と小文字を区別しない場合は StringComparison.OrdinalIgnoreCase) です。

== を使用する際の問題は、作成者が大文字と小文字の区別とカルチャの区別を考慮しているかどうかが明確でないことです。

この件に関する優れた MSDN 記事がここにあります。

于 2009-05-13T17:28:46.190 に答える
-1

stringC#でのを比較する最良の方法は、 aba.Equals(b)が文字列である場合を使用することです。これは、オブジェクトabの値を比較し、オブジェクトの参照に依存しない ため、文字列を比較するための最良の方法です。

" =="記号を使用する場合、両方のオブジェクトが同じ参照を持っていれば結果は等しくなりますが、それらが異なる参照を持ち、同じ値を持っていると問題が発生します。

このcompareTo方法は、他の文字列が他の文字列の前、後、または同じ位置に表示されているかどうかをテストする場合に使用するのに最適な方法であり、それぞれ負の値、正の値、またはゼロの値を返します。パラメータが次の場合も正の値を返しますnull

于 2009-05-13T17:47:55.097 に答える