【问题标题】:Any performance difference between int.Parse() and Convert.Toint()?int.Parse() 和 Convert.Toint() 之间有什么性能差异?
【发布时间】:2009-03-13 02:53:16
【问题描述】:

在 int.Parse() 和 Convert.ToInt32() 之间将字符串转换为整数值有什么明显的优势吗?

string stringInt = "01234";

int iParse = int.Parse(stringInt);

int iConvert = Convert.ToInt32(stringInt);

我发现一个question 询问关于casting vs Convert 但我认为这是不同的,对吧?

【问题讨论】:

  • 这是不同的,是的。
  • 我也很想知道这一点。
  • Ack,我还没有发现两者之间是否存在任何显着的性能差异!

标签: c# performance


【解决方案1】:

当将字符串作为参数传递时,Convert.ToInt32 在内部调用 int.Parse。所以唯一的区别是额外的空检查。

这是来自 .NET Reflector 的代码

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}

【讨论】:

  • 该问题要求“性能”差异。这种“空检查”会招致任何性能损失吗?
  • 宋:当然。空值检查是另一个必须完成的操作。虽然它可能非常小,但会有性能损失。
【解决方案2】:

为了它的价值:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int iterations = 1000000;
            string val = "01234";

            Console.Write("Run 1: int.Parse() ");
            DateTime start = DateTime.Now;
            DoParse(iterations, val);
            TimeSpan duration = DateTime.Now - start;
            Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");

            Console.Write("Run 1: Convert.ToInt32() ");
            start = DateTime.Now;
            DoConvert(iterations, val);
            duration = DateTime.Now - start;
            Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");

            Console.Write("Run 2: int.Parse() ");
            start = DateTime.Now;
            DoParse(iterations, val);
            duration = DateTime.Now - start;
            Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");

            Console.Write("Run 2: Convert.ToInt32() ");
            start = DateTime.Now;
            DoConvert(iterations, val);
            duration = DateTime.Now - start;
            Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");

            Console.Write("Run 3: int.Parse() ");
            start = DateTime.Now;
            DoParse(iterations, val);
            duration = DateTime.Now - start;
            Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");

            Console.Write("Run 3: Convert.ToInt32() ");
            start = DateTime.Now;
            DoConvert(iterations, val);
            duration = DateTime.Now - start;
            Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");

            Console.ReadKey();
        }

        static void DoParse(int iterations, string val)
        {
            int x;
            for (int i = 0; i < iterations; i++)
            {
                x = int.Parse(val);
            }
        }

        static void DoConvert(int iterations, string val)
        {
            int x;
            for (int i = 0; i < iterations; i++)
            {
                x = Convert.ToInt32(val);
            }
        }

    }
}

1,000,000 次迭代的结果:

Run 1: int.Parse() Duration: 312.5ms
Run 1: Convert.ToInt32() Duration: 328.125ms
Run 2: int.Parse() Duration: 296.875ms
Run 2: Convert.ToInt32() Duration: 312.5ms
Run 3: int.Parse() Duration: 312.5ms
Run 3: Convert.ToInt32() Duration: 312.5ms

【讨论】:

  • 正是我想要的! 10k 快乐 :)
【解决方案3】:

不同之处在于两者处理 NULL 值的方式。

当遇到 NULL 值时,Convert.ToInt32 返回值 0。 另一方面,Parse 更敏感,需要一个有效值。 所以当你传入 NULL 时它会抛出异常。

【讨论】:

    【解决方案4】:

    见this discussion for details.

    Convert.ToInt32 不会经常抛出异常(如果 stringInt == null,它会返回 0 而不是抛出异常),但是会产生一些额外的开销,因为它会进行一些额外的检查,然后在内部调用 int.Parse .

    【讨论】:

      【解决方案5】:

      我写了下面的代码,结果是int.parse比convert.toint32慢。

          static void Main(string[] args) {
              Console.WriteLine(TimeConvertTo());
              Console.WriteLine(TimeParse());
          }
      
          static TimeSpan TimeConvertTo() {
              TimeSpan start = DateTime.Now.TimeOfDay;
              for (int i = 0; i < 99999999; i++) {
                  Convert.ToInt32("01234");
              }
              return DateTime.Now.TimeOfDay.Subtract(start);
          }
      
          static TimeSpan TimeParse() {
              TimeSpan start = DateTime.Now.TimeOfDay;
              for (int i = 0; i < 99999999; i++) {
                  int.Parse("01234");
              }
              return DateTime.Now.TimeOfDay.Subtract(start);
          }
      

      【讨论】:

      • 这怎么可能,可能是 99999999 太少了,无法获得有效结果
      【解决方案6】:

      正如其他人所提到的,存在一些性能影响。如果您查看测试代码和性能统计信息from this website:

      • Int.Parse() 和 Int.TryParse() 通常随着您执行的转换次数的增加而执行得更快。
      • Convert.ToInt() 似乎在转换次数较少时表现最佳
      • 无论您需要执行多少次转换,将字符串转换为 int(假设没有例外)的整体最快方法是:

      _

      y = 0; //the resulting number from the conversion
      //loop through every char in the string, summing up the values for the final number
      for (int i = 0; i < s[x].Length; i++) 
          y = y * 10 + (s[x][i] - '0');
      

      【讨论】:

      【解决方案7】:

      两者都很慢。如果你知道输入字符串的确切格式并且关心速度,我建议你自己编写转换函数。

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
      猜你喜欢
      • 2010-10-25
      • 2011-02-04
      • 2012-05-14
      • 1970-01-01
      • 2015-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多