比convert.toint32更有效的将字符串整数转换为int的方法

时间:2012-02-15 19:24:47

标签: c#

是否有更有效的方法将字符串整数转换为int而不是在c#中使用Convert.ToInt32()

我有一个程序可以将很多字符串转换为整数。这些值以字符串格式从文本文件中读取。

5 个答案:

答案 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性能的地方,但这可能不是其中之一。