当前位置: 代码迷 >> C# >> 关于字符串转数字的效率有关问题,int.Parse, int.TryParse, Convert.ToInt32
  详细解决方案

关于字符串转数字的效率有关问题,int.Parse, int.TryParse, Convert.ToInt32

热度:46   发布时间:2016-05-05 04:23:31.0
关于字符串转数字的效率问题,int.Parse, int.TryParse, Convert.ToInt32
我是使用的老赵用来测试VS的profiler的程序,

        private static int Count = 100;

        private static void Main(string[] args)
        {
            var array = Enumerable.Range(1, 3).Select(i => new String((char)(i + 97), 5)).ToArray();

            var sw = new Stopwatch();

            sw.Start();
            TestConvert(array);
            Console.WriteLine(sw.ElapsedMilliseconds);

            sw.Restart();
            TestParse(array);
            Console.WriteLine(sw.ElapsedMilliseconds);

            sw.Restart();
            TestTryParse(array);
            Console.WriteLine(sw.ElapsedMilliseconds);

            Console.ReadKey(false);
        }

        private static List<Int32> TestParse(String[] strings)
        {
            Int32 intValue;
            List<Int32> intList = new List<int>();

            for (int i = 0; i < Count; i++)
            {
                intList.Clear();

                foreach (String str in strings)
                {
                    try
                    {
                        intValue = Int32.Parse(str);
                        intList.Add(intValue);
                    }
                    catch (System.ArgumentException)
                    { }
                    catch (System.FormatException)
                    { }
                    catch (System.OverflowException)
                    { }
                }
            }

            return intList;
        }

        private static List<Int32> TestTryParse(String[] strings)
        {
            Int32 intValue;
            List<Int32> intList = new List<int>();
            Boolean ret;

            for (int i = 0; i < Count; i++)
            {
                intList.Clear();

                foreach (String str in strings)
                {
                    ret = Int32.TryParse(str, out intValue);
                    if (ret)
                    {
                        intList.Add(intValue);
                    }
                }
            }

            return intList;
        }

        private static List<Int32> TestConvert(String[] strings)
        {
            Int32 intValue;
            List<Int32> intList = new List<int>();

            for (int i = 0; i < Count; i++)
            {
                intList.Clear();

                foreach (String str in strings)
                {
                    try
                    {
                        intValue = Convert.ToInt32(str);
                        intList.Add(intValue);
                    }
                    catch (System.FormatException)
                    { }
                    catch (System.OverflowException)
                    { }
                }
            }

            return intList;
        }


运行输出的时候,运行输出的时候给出的结果比较夸张,Parse和Convert给出的数据都是4000多ms,但是TryParse给出的数据是0,用VS2013的Profiler给出的数据也差不多,TryParse基本上不占CPU时间,和老赵给出的Profiler结果大相径庭,请问大家这是什么原因呢?
------解决思路----------------------
Convert ToInt32 底层是调用了int.Parse 所以这两个是一样的。

TryParse
与Parse 区别在于内部,

Parse 是每个if都要判断,Try 的绕过了部份的if 


[SecuritySafeCritical]
internal static unsafe int ParseInt32(string s, NumberStyles style, NumberFormatInfo info)
{
    byte* stackBuffer = stackalloc byte[(IntPtr) NumberBuffer.NumberBufferBytes];
    NumberBuffer number = new NumberBuffer(stackBuffer);
    int num = 0;
    StringToNumber(s, style, ref number, info, false);
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
    {
        if (!HexNumberToInt32(ref number, ref num))
        {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
        }
        return num;
    }
    if (!NumberToInt32(ref number, ref num))
    {
        throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
    }
    return num;
}

 

[SecuritySafeCritical]
internal static unsafe bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result)
{
    byte* stackBuffer = stackalloc byte[(IntPtr) NumberBuffer.NumberBufferBytes];
    NumberBuffer number = new NumberBuffer(stackBuffer);
    result = 0;
    if (!TryStringToNumber(s, style, ref number, info, false))
    {
        return false;
    }
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
    {
        if (!HexNumberToInt32(ref number, ref result))
        {
            return false;
        }
    }
    else if (!NumberToInt32(ref number, ref result))
    {
        return false;
    }
    return true;
}

 



------解决思路----------------------
我也测试了楼主提供的代码,结果为1052,1050,0.。
看了3楼的回答, 觉得应该是Parse方法内部的格式合法性判断耗费了更多的资源,TryParse应该是边判断边解析,如果格式非法,立即返回。
另外我还测试了BitConverter.ToInt32,运行结果为0。 我平时都是用这个。。。
  相关解决方案