gpt4 book ai didi

.net - DataReader 基于名称的查找 - 到底发生了什么,导致它们比循环中基于序数的查找慢得多?

转载 作者:行者123 更新时间:2023-12-02 00:03:58 24 4
gpt4 key购买 nike

使用多个匹配规则时,基于名称的查找可能比整数索引的查找慢一点,这是有道理的。然而,当我们谈论数据集中 10-15 [列] 条目的平均数量时,我很难相信这可以解释每行 3%(或在我的项目中为 5-7%)的相对成本。值得澄清的是,在前面的声明中,我指的是发生这种“取消引用”的列数,而不是数据集中的记录数。上述成本是在这些查找每行发生一次的情况下发生的。所以它们可能会经常发生。

idr.GetOrdinal(name) // Name based lookup
idr[name] // Name-based lookup
idr.GetValue(index) // Ordinal-based lookup

执行基于名称的字段查找实际上是否需要与数据库进行额外的通信?是什么让他们慢得多?

我还注意到获取列名称的代码如下:

List<string> columnList = new List<string>();
for (int i = 0; i < idr.FieldCount; i++)
{
columnList.Add(idr.GetName(i));
}

return columnList;

比使用 GetSchemaTable 的等效版本快得多,我猜这是出于同样的原因。

这个问题的本质源于: Ordinal-Based Lookups vs. Name Based Lookups

最佳答案

以下是 SqlDataReaderGetOrdinal 代码,.NET 4.0,使用 ILSpy 提取。

public override int GetOrdinal(string name)
{
SqlStatistics statistics = null;
int ordinal;
try
{
statistics = SqlStatistics.StartTimer(this.Statistics);
if (this._fieldNameLookup == null)
{
if (this.MetaData == null)
{
throw SQL.InvalidRead();
}
this._fieldNameLookup = new FieldNameLookup(this, this._defaultLCID);
}
ordinal = this._fieldNameLookup.GetOrdinal(name);
}
finally
{
SqlStatistics.StopTimer(statistics);
}
return ordinal;
}

如您所见,没有额外的数据库访问。 FieldNameLookup 使用 Hashtable 来存储字段名称,并在第一次调用 GetOrdinal 时加载后进行缓存。因此,GetOrdinal 调用将为通过 FieldNameLookup 完成的查找添加非常少量的开销,并且 SqlStatistics 调用也可能会增加一点开销开销(虽然可能不多)。

一个好的测试是使用 Hashtable 来存储索引,并在该 Hashtable 中为每行查找每列的索引。如果性能与为每行调用 GetOrdinal 相同,那么您可以放心地假设开销是在 FieldNameLookup 调用中。

希望有帮助。

关于.net - DataReader 基于名称的查找 - 到底发生了什么,导致它们比循环中基于序数的查找慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16286809/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com