检查DBNull然后分配给变量的最有效方法?

这个问题有时会出现,但是我还没有找到满意的答案。


典型的模式是(行是DataRow):


 if (row["value"] != DBNull.Value)

 {

      someObject.Member = row["value"];

 }

我的第一个问题是哪个效率更高(我已经翻转了条件):


  row["value"] == DBNull.Value; // Or

  row["value"] is DBNull; // Or

  row["value"].GetType() == typeof(DBNull) // Or... any suggestions?

这表明.GetType()应该更快,但是也许编译器知道一些我不知道的技巧?


第二个问题,是否值得缓存row [“ value”]的值,或者编译器是否仍然优化了索引器?


例如:


  object valueHolder;

  if (DBNull.Value == (valueHolder = row["value"])) {}

笔记:


row [“ value”]存在。

我不知道列的列索引(因此查找列名)。

我在问有关检查DBNull然后分配的问题(不是关于过早的优化等)。

我对一些场景进行了基准测试(时间以秒为单位,进行了10,000,000次试用):


row["value"] == DBNull.Value: 00:00:01.5478995

row["value"] is DBNull: 00:00:01.6306578

row["value"].GetType() == typeof(DBNull): 00:00:02.0138757

Object.ReferenceEquals具有与“ ==”相同的性能


最有趣的结果?如果您按大小写不匹配列名(例如,使用“值”而不是“值”,则花费的时间大约是字符串的十倍):


row["Value"] == DBNull.Value: 00:00:12.2792374

这个故事的寓意似乎是,如果您无法通过其索引查找列,那么请确保馈入索引器的列名称与DataColumn的名称完全匹配。


缓存值似乎也快了将近一倍:


No Caching: 00:00:03.0996622

With Caching: 00:00:01.5659920

因此,最有效的方法似乎是:


 object temp;

 string variable;

 if (DBNull.Value != (temp = row["value"]))

 {

      variable = temp.ToString();

 }


尚方宝剑之说
浏览 499回答 3
3回答

慕码人8056858

您应该使用以下方法:Convert.IsDBNull()考虑到它是框架的内置组件,我希望它是最有效的。我建议采取以下措施:int? myValue = (Convert.IsDBNull(row["column"]) ? null : (int?) Convert.ToInt32(row["column"]));是的,编译器应该为您缓存它。

PIPIONE

编译器不会优化掉索引(也就是说,如果你使用行[“价值”]两次),所以是的,它是稍微快做:object value = row["value"];然后使用价值两次;如果为null,使用.GetType()可能会引发问题。DBNull.Value实际上是一个单例,因此要添加第4个选项-您也许可以使用ReferenceEquals-但实际上,我认为您在这里担心太多...我认为“ is”,“ ==”之间的速度不会有所不同“等将成为您看到的任何性能问题的原因。分析您的整个代码并专注于重要的事情...并非如此。
打开App,查看更多内容
随时随地看视频慕课网APP