什么是最快的:(int),Convert.ToInt32(x)或Int32.Parse(x)?

以下哪个代码是最快/转换某个对象x的最佳做法?

int myInt = (int)x; 

要么

 int myInt = Convert.ToInt32(x); 

要么

 int myInt = Int32.Parse(x); 

或者在string“s”的情况下,

 int myInt; Int32.TryParse(s, out myInt); 

我很好奇哪个执行最快的数据types有一个方法在转换,而不仅仅是整数。 我只是用int作为例子。

编辑:这种情况来自从数据表获取信息。 Will(int)仍然工作最快?

从一些testing中,当对象x = 123123123时,int执行速度最快,就像很多人所说的那样。 当x是一个string时,Parse运行速度最快(注:cast会抛出一个exception)。 我真正好奇的是,在以下列方式检索值时,它们是如何运行的:

 foreach(DataRow row in someTable.Rows) { myInt = (int)row["some int value"]; myInt2 = Int.Parse(row["some int value"]); myInt2 = Convert.ToInt32(row["some int value"]); } 

你为什么不尝试几千次?

(这是所有“什么是最快的”问题)


嗯,这些年来大量的降薪…我想我应该扩大这个答案。

上述说法在我年轻时有一定程度的轻浮,但我仍然同意这种说法。 花费时间创造一个SO问题是不值得的,在两个或三个操作中,每个操作的时间不到1ms,问他们他们的想法会更快。

事实上,一个人可能需要一个或两个比另一个更长的时间在日常使用中几乎可以忽略不计。 如果您在将数百万个对象转换为整数的过程中发现应用程序中存在性能问题, 那么您可以对实际代码进行剖析,并且可以轻松地testingint转换是否确实是瓶颈。

而今天它是object-int转换器,明天也许你会认为你的对象DateTime转换器需要很长时间。 你会创build另一个SO问题来找出什么是最快的方法?

至于你的情况(毫无疑问,现在已经解决了),正如评论中提到的那样,你正在查询一个数据库,所以object-int转换是你最担心的。 如果我是你,我会使用你提到的任何转换方法。 如果出现问题,我将使用分析器或日志logging来隔离呼叫。 然后,当我注意到object-int转换正在进行一百万次,并且转换所花费的总时间似乎相对较高时,我将更改为使用不同的转换方法和重新configuration文件。 select花费最less时间的转换方法。 你甚至可以在一个单独的解决scheme,甚至LINQPad或Powershell等testing。

这取决于你期望的x是什么

如果x是一个盒装的int,那么(int)x是最快的。

如果x是一个string,但肯定是一个有效的数字,那么int.Parse(x)是最好的

如果x是一个string,但可能无效,那么int.TryParse(x)比try-catch块快得多。

除了最大的循环之外,Parse和TryParse之间的区别是微不足道的。

如果你不知道x是什么(也许是一个string或盒装int),那么Convert.ToInt32(x)是最好的。

对于具有静态Parse和TryParse方法的所有值types,这些通用规则也是如此。

最快!=最佳实践!

例如, (int)几乎肯定是最快的,因为它是一个运算符而不是一个函数调用,但它只能在某些情况下工作。

最好的做法是使用可读性最强的代码,不会对性能产生负面影响,100次整数转换中的99次不会影响应用程序的性能。 如果是,请使用最合适,最窄的转换。 有时候是(int) 。 有时它是TryParse() 。 有时它是Convert.ToInt32()

如果你知道数据肯定是int,那么int myInt = (int)x; 应该是最快的select。 否则, TryParse将帮助您在没有exception缓慢的情况下正确完成任务。

顺便说一句:

(int)因此更快,

(int)IL =

  .locals init ( [0] object x, [1] int32 Y) L_0000: ldc.i4.1 L_0001: box int32 L_0006: stloc.0 L_0007: ldloc.0 L_0008: unbox int32 L_000d: ldobj int32 L_0012: stloc.1 L_0013: ret 

Convert.Toint32 =

 .locals init ( [0] object x, [1] int32 Y) L_0000: ldc.i4.1 L_0001: box int32 L_0006: stloc.0 L_0007: ldloc.0 L_0008: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) L_000d: call int32 [mscorlib]System.Convert::ToInt32(object) L_0012: stloc.1 L_0013: ret 

当我对不同方式之间的性能差异存在疑问时,通常会在我的MeasureIt副本中进行一个新的input,可以从Vance Morrison的MSDN文章中免费下载。 欲了解更多信息,请参阅文章。

通过添加一个简单的代码MeasureIt,我得到下面的结果比较转换为int的各种方法的实际时间的结果。 注意从string转换为int将抛出一个exception,并且是无效的,所以我只是添加了对我有意义的排列。


名称中位数平均标准偏差最小值最大值样本       
 IntCasts:Copy [count = 1000 scale = 10.0] 0.054 0.060 0.014 0.054 0.101 10       
 IntCasts:Cast Int [count = 1000 scale = 10.0] 0.059 0.060 0.007 0.054 0.080 10       
 IntCasts:Cast Object [count = 1000 scale = 10.0] 0.097 0.100 0.008 0.097 0.122 10       
 IntCasts:int.Parse [count = 1000 scale = 10.0] 2.721 3.169 0.850 2.687 5.473 10       
 IntCasts:Convert.ToInt32 [count = 1000 scale = 10.0] 3.221 3.258 0.067 3.219 3.418 10     

为了find您感兴趣的各种types的最佳性能,只需扩展下面的代码,这就是我必须添加到MeasureIt以生成上述表格的字面意思。

 static unsafe public void MeasureIntCasts() { int result; int intInput = 1234; object objInput = 1234; string strInput = "1234"; timer1000.Measure("Copy", 10, delegate { result = intInput; }); timer1000.Measure("Cast Object", 10, delegate { result = (int)objInput; }); timer1000.Measure("int.Parse", 10, delegate { result = int.Parse(strInput); }); timer1000.Measure("Convert.ToInt32", 10, delegate { result = Convert.ToInt32(strInput); }); } 

最好的做法是TryParse,看到结果,如果它的工作 – 否则你可能会得到例外

在.Net 2中优化绑定数据网格时,我发现几乎一半的时间都花在了各种对象的ToString()方法上,这些方法被用作Convert操作的input。 通过隔离这些情况并在可能的情况下通过将其转换为正确的types(因为它们是从数据库中取出的行并且可以依赖这些types),这导致数据绑定操作的速度大大增加。

所以,如果你知道事情的types,并且足够多的时间点击这段代码,那么值得花费精力直接投射,而不是在必要时进行转换。

通过Sam Allen的替代方法扩展了Eric Cosky的testing,我发现如果你知道你的string是一个有效的整数,那么你自己parsing它会快得多。

我扩展了以下情况的testing:

  timer1000.Measure("IntParseFast", 10, delegate { result = Misc.IntParseFast(strInput); }); timer1000.Measure("IntParseUnsafe", 10, delegate { result = Misc.IntParseUnsafe(strInput); }); 

通过以下实现:

 public static int IntParseFast(string value) { int result = 0; int length = value.Length; for (int i = 0; i < length; i++) { result = 10 * result + (value[i] - 48); } return result; } public unsafe static int IntParseUnsafe(string value) { int result = 0; fixed (char* v = value) { char* str = v; while (*str != '\0') { result = 10 * result + (*str - 48); str++; } } return result; } 

我得到以下结果:

 IntCaint.Parse 5,495 IntCaConvert.ToInt32 5,653 IntCaIntParseFast 1,154 IntCaIntParseUnsafe 1,245 

不确定的performance,但这些方法是不一样的。 ParseTryParse都使用string,parsing对象的String表示forms(请参阅MSDN)。

将数字的string表示forms转换为其32位有符号整数等效forms。

不知道关于转换和Convert类,但强制Convert只适用于实际上已经是整数,但没有强types的对象。

马蒂亚斯

如果您需要额外的速度,可以很容易地testing不同的选项。 既然你没有testing它们,你一定不需要它们。 不要浪费你的时间毫无意义的微观优化!

(int)转换string将无法正常工作,所以我不testing它。 Convert.ToInt32将testing的值反映为null,然后调用int.Parse,因此通常应该比int.Parse()慢。

 foreach(DataRow row in someTable.Rows) { myInt = (int)row["some int value"]; myInt2 = Int.Parse(row["some int value"]); myInt2 = Convert.ToInt32(row["some int value"]); } 

对于这个例子,如果来自表的值确实是一个int值,或者可比的数据库值,那么使用

 myInt = (int)row["some int value"]; 

将是最有效的,因此“最快”的原因

 row["some int value"]; 

将会是一个值型的int实例,在一个引用types的对象实例中被装箱,所以使用显式types转换将是最快的,因为其他人说这是一个操作而不是函数调用,从而减less了所需的cpu操作。 调用一个转换或parsing方法将需要额外的cpu操作,因此不能“快速”。

这不是真的。 快速转换是直接演员:

 int i = (int) stringData; watch.Elapsed = {00:00:00.1732388} watch2.Elapsed= {00:00:00.0878196} // Mesary start Stopwatch watch = new Stopwatch(); watch.Start(); for (int f = 1; f < 1000000; f++) { item.Count = FastInt32.IntParseFast(dt.Rows[i]["TopCount"]); } // Execute the task to be timed watch.Stop(); Console.WriteLine("Elapsed: {0}", watch.Elapsed); Console.WriteLine("In milliseconds: {0}", watch.ElapsedMilliseconds); Console.WriteLine("In timer ticks: {0}", watch.ElapsedTicks); // Mesary end // Mesary start Stopwatch watch2 = new Stopwatch(); watch2.Start(); for (int n = 1; n < 1000000; n++) { item.Count = (int)(dt.Rows[i]["TopCount"]); } // Execute the task to be timed watch2.Stop(); Console.WriteLine("Elapsed: {0}", watch2.Elapsed); Console.WriteLine("In milliseconds: {0}", watch2.ElapsedMilliseconds); Console.WriteLine("In timer ticks: {0}", watch2.ElapsedTicks); // Mesary end 

有人已经做了基准。 这是结果。 如果你知道你正在转换什么, 最快的方法将永远是一个有效的int,就是使用下面的方法(上面几个人已经回答了):

 int value = 0; for (int i = 0; i < str.Length; i++) { value = value * 10 + (str[i] - '0'); } 

其他基准testing技术是:

  • Convert.ToInt32
  • Int32.TryParse
  • int.Parse

最后,他们最终打来电话:

 System.Number.ParseInt32(string s, NumberStyles style, NumberFormatInfo info); 

所以总的来说,这样的事情没有什么不同。

看看.Net Reflector来看看这个。