将对象转换为双倍的最快方法?
将对象转换为double的最快方法是什么? 我现在正处于一段代码中,其中包括:
var d = double.TryParse(o.ToString(), out d); // o is the Object...
首先想到的是将其重写为
var d = Convert.ToDouble(o);
但实际上会更快吗?
编辑:除了运行配置文件(顺便说一下,我强烈建议任何开发人员使用JetBrains dotTrace ),我运行了Reflector,这帮助我提出了以下内容(或多或少相关的代码部分):
if (o is IConvertible) { d = ((IConvertible)o).ToDouble(null); } else { d = 0d; }
原始代码double.TryParse()
在140ms内执行。 新代码在34ms内执行。 我几乎可以肯定这是我应该采取的优化路径,但在我这样做之前,有没有人看到我的“优化”代码存在任何问题? 在此先感谢您的反馈!
你必须做大量的这些,以便有任何意义,花时间在这上面。 但是,我不是来判断:
所以,你的代码是这样的:
if (o is IConvertible) { d = ((IConvertible)o).ToDouble(null); } else { d = 0d; }
我想知道你是否会更好
IConvertible convert = o as IConvertible; if (convert != null) { d = convert.ToDouble(null); } else { d = 0d; }
为您节省双重演员。
我尝试了以下方法。
- double.TryParse
- double.Parse
- Convert.ToDouble
我使用了以下代码。
public static void Main() { string text = "3.14"; var timer = new Stopwatch(); timer.Start(); for (int i = 0; i < 10000000; i++) { double d; d = Convert.ToDouble(text); //double.TryParse(text, out d); //d = double.Parse(text); } timer.Stop(); Console.WriteLine("Time=" + timer.Elapsed.ToString()); Console.ReadLine(); }
在我的机器上,我看到了这些结果。 我平均进行了3次不同的跑步。
- double.TryParse = 4.45秒
- double.Parse = 4.45秒
- Convert.ToDouble = 4.75秒
当然,我使用了可转换的字符串。 如果字符串不可转换,那么我非常怀疑double.TryParse
将是最快的。
使用System.Diagnostics.Stopwatch创建一个小型测试应用程序,看看哪个更快。 虽然我认为这不会产生有价值的差异。 纯粹为了可读性,我会选择Convert.ToDouble
。
首先,如果您真的想知道哪个更快,您应该编写一个快速测试(使用您希望处理的数据)并为每个选项计时。 在不知道(或可能是)的情况下,很难判断。 我怀疑你不会看到太大的不同。
其次,除非你在代码的一个极其时间关键的部分调用这段代码,并称它为数千次启动时间,否则我怀疑它真的很重要。 写好,干净的代码, 然后优化。
你可能会尝试做几件不同的事情,这取决于o是什么类型的东西。 它可能是
a)盒装双,你只想取消它:
object o = 53.2; double d = (double)o;
b)一些其他类型,值或引用,有一些转换为double可用(实现IConvertible.ToDouble())你想要使用
object o = 53.2M; // a System.Decimal double d = Convert.ToDouble(o);
要么
c)具有默认字符串表示的东西,可以解析为double
object o = "53.2"; double d; bool convertedOK = double.TryParse(o.ToString(), out d);
在某种意义上,选项c是最长的一种方式; 你正在接受你的对象,询问它的字符串表示,然后尝试解析该字符串以获得双精度。 如果你不需要这样做,那就太笨了,在40,000个调用的例子中,它将创建并丢弃40,000个字符串……
如果您知道您的对象将始终包含实现转换为double的内容,则可以跳过所有内容并转到选项b。 如果你知道你的对象只是一个盒装双,那么选择最简单的选项(a)来取消它。
如果你真的不知道将会是什么,也许这些方面的东西对你有用吗?
double d = (o is double) ? (double)o : (o is IConvertible) ? (o as IConvertible).ToDouble(null) : double.Parse(o.ToString());
(注意:如果o包含实现IConvertible但无法转换为double的内容,或者无法将其字符串表示forms解析为double,则此方法无效)
我还没有说过相对速度,但是如果拆箱比转换成字符串然后解析要快得多(除非优化器非常聪明),我会感到惊讶。
使用.NET秒表在LINQPad中进行快速测试表明存在很大差异。
IEnumerable
在我的电脑上给出以下结果
System.String: 10000000 iterations took 1329ms System.Decimal: 10000000 iterations took 402ms System.Double: 10000000 iterations took 38ms