Is there a faster way to convert a string
to double
than Convert.ToDouble
?
I have monitored System.Conv
double.Parse() should be a little bit faster.
I'm unable to reproduce this. This code tests the speed of Convert.ToDouble
.
int numTests = 10000;
double sum = 0;
var sw = Stopwatch.StartNew();
for (int i = 0; i < numTests; ++i)
{
var d = Convert.ToDouble("1.23456");
sum += d;
}
sw.Stop();
Console.WriteLine("{0} tests @ {1} ms. Avg of {2:N4} ms each", numTests,
sw.ElapsedMilliseconds, (double)sw.ElapsedMilliseconds/numTests);
Console.WriteLine("sum = {0}", sum);
With 10,000 calls, I get
10000 tests @ 3 ms. Avg of 0.0003 ms each
sum = 12345.6000000021
That's in release mode, running without the debugger attached.
It's highly unlikely that the problem is with Convert.ToDouble
.
If you are 100% sure about your source data format and range, you can use:
string num = "1.34515";
int len = num.Length - num.IndexOf('.') - 1;
int intval = Int32.Parse(num.Replace(".", ""));
double d = (double)intval / PowersOf10[len]; // PowersOf10 is pre-computed or inlined
It worked ~50% faster than Double.Parse
for me, but I wouldn't use it in any serious applications - it's extremely limited compared to proper parsing and I can't think of process where you need to parse millions of doubles and a few milliseconds would make the difference.
You can call double.Parse("1.34515");
which is what Convert.ToDouble
wraps.
It may be quicker to call double.TryParse
which will avoid the exception overhead.
You could try decreasing the number of calls to Thread.CurrentCulture
by using the Double.Parse(String, NumberStyles, IFormatProvider)
overload. Although I doubt it would make a significant difference.
It may occur that parsing to another type: float
or decimal
may win a couple percent.
Kind of a mad idea, but... You could cache the NumberFormatInfo
instance and use reflection to call the internal System.Number.ParseDouble
directly. This would decrease the number of calls to NumberFormatInfo.GetInstance()
, but to be honest, I'd expect reflection to be much slower.
The only option left (except for avoiding parsing) is using some custom parsing method. For example, if you define a strict format for the numbers (e.g. #.####
), you could probably end up with a faster, yet less flexible and/or safe implementation. But taking into account that built-in parsing is half-native, I doubt you'll win.
UPDATE
I've analyzed the .NET code a bit more and found out that NumberFormatInfo
is a IFormatProvider
. So it seems like the fastest code should be:
IFormatProvider _CachedProvider = NumberFormatInfo.CurrentInfo;
var value1 = double.Parse(str1, NumberStyles.Number, _CachedProvider);
var value2 = double.Parse(str2, NumberStyles.Number, _CachedProvider);
This code should decrease the time spent for parsing preparation as much as it's possible. If you parse a lot of string pairse, you could also extract the IFormatProvider
caching to an external code that (possibly) runs a loop and win another couple of milliseconds.
Function in this post Faster alternative to decimal.Parse is based on Jeffrey Sax's code. It adds support for negative numbers, optimizes performance by caching input.Length into a variable and works also for larger numbers.