80

私のアプリケーションは、VSTO を使用して Excel ファイルを読み取り、読み取ったデータをStringDictionary. 数桁の数字 (1000 1000,2 1000,34 - コンマはロシア標準の区切り文字) であるデータのみを追加します。

現在の文字列が適切な数値であるかどうかを確認するにはどうすればよいですか?

object data, string key; // data had read

try
{
  Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
  dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
  // is not a number
}

また

double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
  dic.Add(key, str);
}

次の解析アルゴリズムの問​​題StringDictionaryのため、代わりに使用する必要があります。Dictionary<string, double>

私の質問: どちらの方法が速いですか? どちらがより安全ですか?

そして、電話する方が良いですかConvert.ToDouble(object)、それともConvert.ToDouble(string)ですか?

4

11 に答える 11

133

リリースモードで簡単な非科学的テストを行いました。「2.34523」と「badinput」の 2 つの入力を両方のメソッドに使用し、1,000,000 回繰り返しました。

有効な入力:

Double.TryParse = 646ms
Convert.ToDouble = 662 ms

予想通り、あまり変わらない。すべての意図と目的のために、有効な入力のために、これらは同じです。

無効入力:

Double.TryParse = 612ms
Convert.ToDouble = ..

ええと..それは長い間実行されていました。1,000 回の反復を使用して全体を再実行しましたが、Convert.ToDouble入力が悪い場合は 8.3 秒かかりました。平均すると、2時間以上かかります。無効な入力の場合、テストがどれほど基本的であるかは気にしませんConvert.ToDouble。例外が発生すると、パフォーマンスが低下します。

TryParseそれで、それを裏付けるいくつかの数字とともに、ここに別の投票があります。

于 2009-02-25T15:44:38.187 に答える
46

まず、そもそもではdouble.Parseなく使用します。Convert.ToDouble

Parseまたはを使用する必要があるかどうかについてはTryParse、入力データが正しくない場合に続行できますか、それとも本当に例外的な状態ですか? 例外的に使用Parseし、入力が悪い場合は爆破させます。予期されていて、きれいに処理できる場合は、 を使用しますTryParse

于 2009-02-25T15:29:11.140 に答える
8

.NET Framework の設計ガイドラインでは、Try メソッドの使用が推奨されています。通常は、例外を回避することをお勧めします。

Convert.ToDouble(object)しましょう((IConvertible) object).ToDouble(null);

どちらが呼び出されますかConvert.ToDouble(string, null)

したがって、文字列バージョンを呼び出す方が高速です。

ただし、文字列バージョンはこれを行うだけです:

if (value == null)
{
    return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);

double.Parseしたがって、直接実行する方が高速です。

于 2009-02-25T15:26:10.210 に答える
7

例外を処理しない場合は、TryParse を使用してください。TryParse は、例外スタック トレース全体を処理する必要がないため、高速です。

于 2009-02-25T15:26:59.477 に答える
7

私は通常、クラスを避けようとしConvertます (つまり、私はそれを使用しません)。これは、非常に紛らわしいためです。Convert同じコードで多くの意味的に非常に異なる変換が発生する可能性があるため、コードは、ここで正確に何が起こるかについてほとんどヒントを与えません。 . これにより、プログラマーが正確に何が起こっているのかを制御することが難しくなります。

したがって、私のアドバイスは、このクラスを使用しないことです。ToStringこれも実際には必要ありません (数値クラスの通常の方法ではこれを行うための適切な方法が提供されないため、数値のバイナリ形式を除きます)。

于 2009-02-25T15:27:19.880 に答える
7

めったにないケースですが、入力が 100% 確実でない限り、Double.TryParse を使用する必要があります。

Convert.ToDouble will throw an exception on non-numbers
Double.Parse will throw an exception on non-numbers or null
Double.TryParse will return false or 0 on any of the above without generating an exception.

例外よりも遅くはないため、例外をスローすると、解析の速度は二次的なものになります。

于 2011-12-19T15:11:27.187 に答える
4

Convert クラスには多くの嫌悪感があります... バランスを取るために、Convert には利点が 1 つあります。オブジェクトを渡された場合、

Convert.ToDouble(o);

o が既に Double (または int または容易にキャスト可能なもの) である場合、値を簡単に返すことができます。

Double.Parse または Double.TryParse を使用することは、既に文字列に含まれている場合に最適ですが、

Double.Parse(o.ToString());

最初に文字列を解析する必要があり、入力によってはより高価になる可能性があります。

于 2015-09-14T20:49:43.197 に答える
2

Double.TryParse IMO。

エラーが発生した場所を正確に知ることができます。

次に、false が返された場合 (つまり、変換できなかった場合) に適切と思われる方法で処理できます。

于 2009-02-25T15:26:58.273 に答える
2

TryParse()例外を気にせずに変換の成功または失敗を吐き出すため、私は常にメソッドを使用することを好みました。

于 2009-02-25T15:28:35.540 に答える
1

個人的には、このTryParseメソッドの方が読みやすいと思います。実際にどちらを使用するかは、ユースケースによって異なります。エラーをローカルで処理できる場合は、エラーが予想され、ブール値TryParseが適切であると考えられます。そうでない場合は、例外は飛びます。

TryParse例外処理のオーバーヘッドが回避されるため、高速化も期待できます。ただし、 Jon Skeet の MiniBenchなどのベンチマーク ツールを使用して、さまざまな可能性を比較してください。

于 2009-02-25T15:29:16.537 に答える