Я заметил, что decimal.Parse(number, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture)
примерно на 100% медленнее, чем пользовательский метод десятичного разбора, основанный на коде Джеффри Сакса из Более быстрая альтернатива Convert.ToDouble
public static decimal ParseDecimal(string input) {
bool negative = false;
long n = 0;
int len = input.Length;
int decimalPosition = len;
if (len != 0) {
int start = 0;
if (input[0] == '-') {
negative = true;
start = 1;
}
for (int k = start; k < len; 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, negative, (byte)(len -decimalPosition));
}
Я предполагаю, что это потому, что native decimal.Parse
предназначен для борьбы с типом номера и информацией о культуре.
Однако вышеупомянутый метод не использует 3-й параметр hi byte в new decimal
, поэтому он не будет работать с большими числами.
Есть ли более быстрая альтернатива decimal.Parse
для преобразования строки, состоящей только из чисел и десятичной точки в десятичную, что будет работать с большими числами?
EDIT: контрольный показатель:
var style = System.Globalization.NumberStyles.AllowDecimalPoint;
var culture = System.Globalization.CultureInfo.InvariantCulture;
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
s.Reset();
s.Start();
for (int i=0; i<10000000; i++)
{
decimal.Parse("20000.0011223344556", style, culture);
}
s.Stop();
Console.WriteLine(s.Elapsed.ToString());
s.Reset();
s.Start();
for (int i=0; i<10000000; i++)
{
ParseDecimal("20000.0011223344556");
}
s.Stop();
Console.WriteLine(s.Elapsed.ToString());
выход:
00:00:04.2313728
00:00:01.4464048
Пользовательский ParseDecimal в этом случае значительно быстрее, чем decimal.Parse.