为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

尚方宝剑之说 2019-10-05 15:02:27
这个问题有时会出现,但是我还没有找到满意的答案。典型的模式是(行是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.5478995row["value"] is DBNull: 00:00:01.6306578row["value"].GetType() == typeof(DBNull): 00:00:02.0138757Object.ReferenceEquals具有与“ ==”相同的性能最有趣的结果?如果您按大小写不匹配列名(例如,使用“值”而不是“值”,则花费的时间大约是字符串的十倍):row["Value"] == DBNull.Value: 00:00:12.2792374这个故事的寓意似乎是,如果您无法通过其索引查找列,那么请确保馈入索引器的列名称与DataColumn的名称完全匹配。缓存值似乎也快了将近一倍:No Caching: 00:00:03.0996622With Caching: 00:00:01.5659920因此,最有效的方法似乎是: object temp; string variable; if (DBNull.Value != (temp = row["value"])) {      variable = temp.ToString(); }
查看完整描述

3 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

您应该使用以下方法:


Convert.IsDBNull()

考虑到它是框架的内置组件,我希望它是最有效的。


我建议采取以下措施:


int? myValue = (Convert.IsDBNull(row["column"]) ? null : (int?) Convert.ToInt32(row["column"]));

是的,编译器应该为您缓存它。


查看完整回答
反对 回复 2019-10-05
?
PIPIONE

TA贡献1829条经验 获得超9个赞

编译器不会优化掉索引(也就是说,如果你使用行[“价值”]两次),所以是的,它是稍微快做:


object value = row["value"];

然后使用价值两次;如果为null,使用.GetType()可能会引发问题。


DBNull.Value实际上是一个单例,因此要添加第4个选项-您也许可以使用ReferenceEquals-但实际上,我认为您在这里担心太多...我认为“ is”,“ ==”之间的速度不会有所不同“等将成为您看到的任何性能问题的原因。分析您的整个代码并专注于重要的事情...并非如此。


查看完整回答
反对 回复 2019-10-05
  • 3 回答
  • 0 关注
  • 498 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信