以下哪个代码是转换某些对象x的最快/最佳实践?
int myInt = (int)x;
要么
int myInt = Convert.ToInt32(x);
要么
int myInt = Int32.Parse(x);
或者在字符串's'的情况下
int myInt; Int32.TryParse(s, out myInt);
我很好奇哪个数据类型在转换中有一个方法的速度最快,而不仅仅是整数.我只是用int作为例子.
编辑:这种情况起因于从数据表中获取信息.Will(int)仍然能以最快的速度运行吗?
从某些测试来看,当对象x = 123123123时,int执行速度最快,就像许多人所说的那样.当x是一个字符串时,Parse运行速度最快(注意:cast抛出异常).我真正好奇的是,当以下列方式检索值时,它们是如何运行的:
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"]); }
Keith.. 79
如果x是盒装int,则(int)x
最快.
如果x是一个字符串,但绝对是有效数字,那么int.Parse(x)
最好
如果x是一个字符串但它可能无效,则int.TryParse(x)
比try-catch块快得多.
除了最大的循环之外,Parse和TryParse之间的差异可以忽略不计.
如果你不知道x是什么(可能是一个字符串或一个盒装的int),那么Convert.ToInt32(x)
最好.
对于具有静态Parse和TryParse方法的所有值类型,这些通用规则也适用.
如果x是盒装int,则(int)x
最快.
如果x是一个字符串,但绝对是有效数字,那么int.Parse(x)
最好
如果x是一个字符串但它可能无效,则int.TryParse(x)
比try-catch块快得多.
除了最大的循环之外,Parse和TryParse之间的差异可以忽略不计.
如果你不知道x是什么(可能是一个字符串或一个盒装的int),那么Convert.ToInt32(x)
最好.
对于具有静态Parse和TryParse方法的所有值类型,这些通用规则也适用.
最快!=最佳实践!
例如,(int)
几乎可以肯定是最快的,因为它是一个操作符而不是函数调用,但它只能在某些情况下工作.
最佳做法是使用最易读的代码,不会对性能产生负面影响,100次整数转换中的99次不会影响应用程序的性能.如果是,请使用最合适,最窄的转换.有时那是(int)
.有时它是TryParse()
.有时它是Convert.ToInt32()
.
你为什么不试试几千次呢?
(这适用于所有"最快的东西:"问题)
嗯,这些年来有很多次投票......我想我应该扩大这个答案.
上述陈述在我年轻时有一定程度的轻率,但我仍然同意其观点.花费时间创建一个SO问题是不值得的,要求其他人在两次或三次不少于1ms的操作中更快地考虑他们的想法.
在日常使用中,人们可能需要一个或两个比另一个周期更长的事实几乎肯定是可以忽略不计的.如果您在将数百万个对象转换为int时在应用程序中发现性能问题,那么您可以分析实际代码,并且您可以轻松地测试int转换是否实际上是瓶颈.
而今天它是object-int转换器,明天也许你会认为你的object-DateTime转换器需要很长时间.你会创建另一个SO问题来找出最快的方法吗?
至于你的情况(毫无疑问很久以来就已经解决了),如评论中所提到的,你正在查询数据库,所以对象-int转换是你最不担心的.如果我是你,我会使用你提到的任何转换方法.如果出现问题,我会使用分析器或记录来隔离呼叫.然后,当我注意到object-int转换正在进行一百万次并且转换所花费的总时间似乎相对较高时,我将改为使用不同的转换方法并重新配置.选择花费最少时间的转换方法.您甚至可以在单独的解决方案中测试它,甚至是LINQPad或Powershell等.
如果你知道数据肯定是int,那么int myInt = (int)x;
应该是最快的选择.否则TryParse
将帮助您在没有异常缓慢的情况下做到正确.
BTW:
(int)因此只有unboxes更快,
(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副本中创建一个新条目,可以从Vance Morrison的一篇很棒的MSDN文章中免费下载.有关更多信息,请参阅文章.
通过向MeasureIt添加一些简单的代码,我得到下面的结果,比较各种转换为int的方法的实际时间.注意从string到int的强制转换将抛出异常并且无效,所以我只添加了对我有意义的排列.
Name Median Mean StdDev Min Max Samples 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
要找到您感兴趣的各种类型的最佳性能,只需扩展下面的代码,这实际上是我必须添加到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,看看结果如果有效 - 否则你可能会遇到异常