为什么在循环访问DataTable列时第二种方法会变慢
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在循环访问DataTable列时第二种方法会变慢相关的知识,希望对你有一定的参考价值。
我有一个非常大的DataTable~4百万行。
我需要计算表中的列,如果我在方法(Go1)中处理整个列,它比Go2更快,我遍历行并调用每行的方法。
我需要使用Go2方法,因为稍后我需要向表中添加更多行并更新所有列。
但是为什么Go2接近慢 - 它只是每次调用ProcessRow()的开销吗?
有解决方法吗?
public static void AddSignal()
{
foreach (DataRow row in Data.Rows)
{
row[x] = (invertSignal ? -1:1)*Math.Sign(row.Field<double>(y) - row.Field<double>(y));
}
}
public class ByRowAddSignal
{
DataRow row;
public ByRowAddSignal()
{
}
public void ProcessRow(int r)
{
row = Data.Rows[r];
row[x] = (invertSignal ? -1 : 1) * Math.Sign(row.Field<double>(y) - row.Field<double>(y));
}
}
Public static DataTable Data;
public void Go1()
{
Data = LoadData();
AddSignal();
}
public void Go2()
{
Data = LoadData();
ByRowAddSignal byRowAddSignal = new ByRowAddSignal ();
for (int r = 0; r < Data.Rows.Count; r++)
{
byRowAddSignal.ProcessRow(r);
}
}
答案
查看DataRowCollection
的代码,我们发现以下内容:
public DataRow this[int index]
{
get
{
return ((RBTree<DataRow>)this.list)[index];
}
}
RBTree<K>
实际上是一个树而不是数组支持列表,因此索引到它是很复杂的,因为在每个索引调用中你需要迭代到aproproate元素。来自RBTree<K>
的代码显示了这一点:
public K this[int index]
{
get
{
return this.Key(this.GetNodeByIndex(index).NodeID);
}
}
private NodePath GetNodeByIndex(int userIndex)
{
int num;
int mainTreeNodeID = default(int);
if (this._inUseSatelliteTreeCount == 0)
{
num = this.ComputeNodeByIndex(this.root, userIndex + 1);
mainTreeNodeID = 0;
}
else
{
num = this.ComputeNodeByIndex(userIndex, out mainTreeNodeID);
}
if (num == 0)
{
if (TreeAccessMethod.INDEX_ONLY == this._accessMethod)
{
throw ExceptionBuilder.RowOutOfRange(userIndex);
}
throw ExceptionBuilder.InternalRBTreeError(RBTreeError.IndexOutOFRangeinGetNodeByIndex);
}
return new NodePath(num, mainTreeNodeID);
}
private int ComputeNodeByIndex(int x_id, int index)
{
while (x_id != 0)
{
int num = this.Left(x_id);
int num2 = this.SubTreeSize(num) + 1;
if (index < num2)
{
x_id = num;
}
else
{
if (num2 >= index)
{
break;
}
x_id = this.Right(x_id);
index -= num2;
}
}
return x_id;
}
注意使用ILSpy反编译的代码
以上是关于为什么在循环访问DataTable列时第二种方法会变慢的主要内容,如果未能解决你的问题,请参考以下文章
c#中datatable绑定comboBox显示数据有重复怎么处理?取值时未用SQL语句。
javascript,为啥在播放视频时第二行无法从第一行替换?