Double.TryParse or Convert.ToDouble - which is fas

2019-01-06 12:40发布

My application reads an Excel file using VSTO and adds the read data to a StringDictionary. It adds only data that are numbers with a few digits (1000 1000,2 1000,34 - comma is a delimiter in Russian standards).

What is better to check if the current string is an appropriate number?

object data, string key; // data had read

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

or

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

I have to use StringDictionary instead of Dictionary<string, double> because of the following parsing algorithm issues.

My questions: Which way is faster? Which is safer?

And is it better to call Convert.ToDouble(object) or Convert.ToDouble(string) ?

11条回答
女痞
2楼-- · 2019-01-06 13:19

Lots of hate for the Convert class here... Just to balance a little bit, there is one advantage for Convert - if you are handed an object,

Convert.ToDouble(o);

can just return the value easily if o is already a Double (or an int or anything readily castable).

Using Double.Parse or Double.TryParse is great if you already have it in a string, but

Double.Parse(o.ToString());

has to go make the string to be parsed first and depending on your input that could be more expensive.

查看更多
ら.Afraid
3楼-- · 2019-01-06 13:20

This is an interesting old question. I'm adding an answer because nobody noticed a couple of things with the original question.

Which is faster: Convert.ToDouble or Double.TryParse? Which is safer: Convert.ToDouble or Double.TryParse?

I'm going to answer both these questions (I'll update the answer later), in detail, but first:

For safety, the thing every programmer missed in this question is the line (emphasis mine):

It adds only data that are numbers with a few digits (1000 1000,2 1000,34 - comma is a delimiter in Russian standards).

Followed by this code example:

Convert.ToDouble(regionData, CultureInfo.CurrentCulture);

What's interesting here is that if the spreadsheets are in Russian number format but Excel has not correctly typed the cell fields, what is the correct interpretation of the values coming in from Excel?

Here is another interesting thing about the two examples, regarding speed:

catch (InvalidCastException)
{
    // is not a number
}

This is likely going to generate MSIL that looks like this:

catch [mscorlib]System.InvalidCastException 
{
  IL_0023:  stloc.0
  IL_0024:  nop
  IL_0025:  ldloc.0
  IL_0026:  nop
  IL_002b:  nop
  IL_002c:  nop
  IL_002d:  leave.s    IL_002f
}  // end handler
IL_002f: nop
IL_0030: return

In this sense, we can probably compare the total number of MSIL instructions carried out by each program - more on that later as I update this post.

I believe code should be Correct, Clear, and Fast... In that order!

查看更多
Viruses.
4楼-- · 2019-01-06 13:25

The .NET Framework design guidelines recommend using the Try methods. Avoiding exceptions is usually a good idea.

Convert.ToDouble(object) will do ((IConvertible) object).ToDouble(null);

Which will call Convert.ToDouble(string, null)

So it's faster to call the string version.

However, the string version just does this:

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

So it's faster to do the double.Parse directly.

查看更多
smile是对你的礼貌
5楼-- · 2019-01-06 13:26

If you aren't going to be handling the exception go with TryParse. TryParse is faster because it doesn't have to deal with the whole exception stack trace.

查看更多
Summer. ? 凉城
6楼-- · 2019-01-06 13:27

Double.TryParse IMO.

It is easier for you to handle, You'll know exactly where the error occurred.

Then you can deal with it how you see fit if it returns false (i.e could not convert).

查看更多
登录 后发表回答