是否有更有效的方法将字符串整数转换为int而不是在c#中使用Convert.ToInt32()
?
我有一个程序可以将很多字符串转换为整数。这些值以字符串格式从文本文件中读取。
答案 0 :(得分:3)
不,可能不是,至少到目前为止还没有。我试过这个快速而又脏的基准:
private static int toint(string s) {
int res = 0;
foreach (var c in s) {
res = 10*res + (c - '0');
}
return res;
}
static void Main() {
var s = DateTime.Now;
for (int i = 0 ; i != 10000000 ; i++) {
if (Convert.ToInt32("112345678") == 0) break;
}
var m = DateTime.Now;
for (int i = 0; i != 10000000; i++) {
if (toint("112345678") == 0) break;
}
Console.WriteLine("{0} {1}", DateTime.Now-m, m-s);
}
我的toint
方法会跳过各种验证,得到的结果仅比Convert.ToInt32
提高了40%:1.14秒与1.86秒。
仅向脏toint
添加基本验证几乎完全消除了它的优势:此方法
private static int toint(string s) {
int res = 0;
foreach (var c in s) {
if (Char.IsDigit(c))
res = 10*res + (c - '0');
}
return res;
}
在1.62秒内运行,或者在保持根本不正确的情况下增加13%。
答案 1 :(得分:2)
使用此方法:
private static int Parse(string s)
{
int value = 0;
for (var i = 0; i < s.Length; i++)
{
value = value*10 + (s[i] - '0');
}
return value;
}
我获得 750毫秒而不是 18+秒与int.Parse
进行100M转换。
我不会推荐它,除非这是你真正的瓶颈而且你不关心任何形式的验证。
答案 2 :(得分:1)
如果您正在从Stream
读取整数,那么您可以通过避免初始化字符串的开销进行优化。
例如,假设您的号码始终为非负数并以,
字符终止,您可以使用:
int num = stream.ReadByte() - '0';
byte next = (byte)stream.ReadByte();
while (next != ',')
{
num = num * 10 + next - '0';
next = (byte)stream.ReadByte();
}
答案 3 :(得分:1)
This page基准4种技术。最快的方法是Romain在上面写的:
y = 0;
for (int i = 0; i < s[x].Length; i++)
y = y * 10 + (s[x][i] - '0');
以下是一些other methods that were tested,证明速度差了近10倍(其中“s”是作者用于转换的字符串数组):
int.Parse(s[x]);
Int32.TryParse(s[x], out y);
Convert.ToInt32(s[x]);
答案 4 :(得分:0)
Convert.ToInt32()
使用Int32.Parse()
(稍加验证)。 Int32.Parse()
反过来使用Number.Parse()
。
除非你对输入值有重要的了解,否则实际的实现速度和你能得到的一样快(例如,你的输入总是固定的数字位数,它永远不是十六进制,有一定的精度,它总是无符号的,等)
private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value) {
Int32 i = number.scale;
if (i > Int64Precision || i < number.precision) {
return false;
}
char* p = number.digits;
BCLDebug.Assert(p != null, "");
Int64 n = 0;
while (--i >= 0) {
if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10)) {
return false;
}
n *= 10;
if (*p != '\0') {
n += (Int32)(*p++ - '0');
}
}
if (number.sign) {
n = -n;
if (n > 0) {
return false;
}
}
else {
if (n < 0) {
return false;
}
}
value = n;
return true;
}
我在我自己的基础框架中广泛使用Convert.ToXYZ()
方法,在探查器会话中,即使在单个操作中调用了数百次(例如反序列化复杂的对象树),它们也代表了一些微不足道的开销。 / p>
我遇到过可以通过专门算法改善BCL性能的地方,但这可能不是其中之一。