Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
574 views
in Technique[技术] by (71.8m points)

c# - Faster alternative to Convert.ToDouble(string)

Is there a faster way to convert a string to double than Convert.ToDouble?

I have monitored System.Convert.ToDouble(string) calls and its degrading my app performance.

Convert.ToDouble("1.34515");

Perfomance screenshot

WORKING ANSWER FROM Jeffrey Sax :

static decimal[] decimalPowersOf10 = { 1m, 10m, 100m, 1000m, 10000m, 100000m, 1000000m }; 
static decimal CustomParseDecimal(string input) { 
    long n = 0; 
    int decimalPosition = input.Length; 
    for (int k = 0; k < input.Length; k++) { 
        char c = input[k]; 
        if (c == '.') 
            decimalPosition = k + 1; 
        else 
            n = (n * 10) + (int)(c - '0'); 
    } 
    return n / decimalPowersOf10[input.Length - decimalPosition]; 

}

After Jeffrey Sax CustomParser

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can save about 10% by calling Double.TryParse with specific cached instances of NumberStyles and IFormatProvider (i.e. CultureInfo):

var style = System.Globalization.NumberStyles.AllowDecimalPoint;
var culture = System.Globalization.CultureInfo.InvariantCulture;
double.TryParse("1.34515", style, culture, out x);

Both Convert.ToDouble and Double.Parse or Double.TryParse have to assume the input can be in any format. If you know for certain that your input has a specific format, you can write a custom parser that performs much better.

Here's one that converts to decimal. Conversion to double is similar.

static decimal CustomParseDecimal(string input) {
    long n = 0;
    int decimalPosition = input.Length;
    for (int k = 0; k < input.Length; k++) {
        char c = input[k];
        if (c == '.')
            decimalPosition = k + 1;
        else
            n = (n * 10) + (int)(c - '0');
    }
    return new decimal((int)n, (int)(n >> 32), 0, false, (byte)(input.Length - decimalPosition));
}

My benchmarks show this to be about 5 times faster than the original for decimal, and up to 12 times if you use ints.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...