这个问题有时会出现,但是我还没有找到满意的答案。
一个典型的模式是(行是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具有与“ ==”相同的性能
最有趣的结果?如果您按大小写不匹配列名(例如,用“ Value”代替“ value”,则花费的时间大约是字符串的十倍):
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();
}
IDataRecord
扩展。