C# 读取2D矩阵的最快方法
我使用嵌套字典来存储一个2D矩阵,该矩阵在初始化时具有已知值,我发现它太慢,无法读取。还有更快的吗 更新 我不是在寻找我的代码“不工作”的任何原因。它工作正常-但我想知道任何方法,使它更快。下面的详细信息将提供上下文 我还尝试过使用自定义类作为键来展平嵌套字典,但速度更慢 细节 我有一个500-7000个对象的列表,我需要为每个可能的组合(250000-49000000)存储一个值 每个可能的组合都有一个默认值。此值将根据对象之间的依赖关系而更改,每个对象平均有1个依赖关系。对于每个依赖项,将有1-100个更新。每次更新平均会读取5次值 例如,我有1700个对象用于2890000个可能的组合,有1900个依赖项,这意味着9500-95000次读取。此示例的计算时间超过90秒 这是初始化代码。我对这个部分很满意,因为它在不到一秒钟的时间内就完成了C# 读取2D矩阵的最快方法,c#,performance,dictionary,multidimensional-array,profiling,C#,Performance,Dictionary,Multidimensional Array,Profiling,我使用嵌套字典来存储一个2D矩阵,该矩阵在初始化时具有已知值,我发现它太慢,无法读取。还有更快的吗 更新 我不是在寻找我的代码“不工作”的任何原因。它工作正常-但我想知道任何方法,使它更快。下面的详细信息将提供上下文 我还尝试过使用自定义类作为键来展平嵌套字典,但速度更慢 细节 我有一个500-7000个对象的列表,我需要为每个可能的组合(250000-49000000)存储一个值 每个可能的组合都有一个默认值。此值将根据对象之间的依赖关系而更改,每个对象平均有1个依赖关系。对于每个依赖项,将有
var allCombinations = new Dictionary<int, Dictionary<int, int>>();
foreach (var thisObject in allObjects)
{
var comboFor1Object = new Dictionary<int, int>();
foreach (var otherObject in allObjects)
{
comboFor1Object.Add(otherObject.Id, (thisObject.Id == otherObject.Id ? 0 : 100));
}
allCombinations.Add(thisObject.Id, comboFor1Object);
}
根据我对原始问题的评论,我将创建一个值类型(或者,如果您的C#/.NET版本支持
ValueTuple
,请使用该类型):
这样,您的初始化代码应该如下所示:
var allCombinations = new Dictionary<IdById, int>();
foreach (var thisObj in allObjects)
{
foreach (var otherObj in allObjects)
{
var ids = new IdById(thisObj.Id, otherObj.Id);
allCombinations[ids] = (ids.Id1 == ids.Id2 ? 0 : 100);
}
}
最终这是否会更快,您需要测试…使用注释中的dumetrulo建议的2D数组的速度是使用嵌套字典进行读取的速度的两倍。尽管如此,我还是愿意接受任何更快的想法
for (int i = 0; i < allObjects.Count; i++)
{
//new property to record the index in the array
allObjects[i].Index = i;
}
var allCombinations = new int[allObjects.Count, allObjects.Count];
foreach (var thisObj in allObjects)
{
foreach (var otherObj in allObjects)
{
allCombinations[thisObj.Index, otherObj.Index] = (thisObj.Id == otherObj.Id ? 0 : 100);
}
}
您能显示ID、FromObjectId和ToObjd属性的代码吗?@ RS232考虑它们只是属性(It32),您的对象列表<代码> Objbass<代码>更改吗?如果不是,如果你的<代码> ID >代码>可以映射到数组索引,考虑使用2D数组,那肯定会更快。否则,我建议使用
Id
的ValueTuple
(或者,如果使用早期的C版本,则创建自己的结构)作为键,这样就可以删除第二层字典。@dumetruloallObjects
不会更改。不过,每当我查询列表时,我都必须进行某种索引,我会尝试一下。我已经试着用一个类作为键而不是元组来删除第二层字典,但是速度非常慢。我以前没见过valuetuple,我也会试试。谢谢我已经测试过了,结构速度慢了,哇,慢了。我重写了GetHashCode()方法,该方法加快了速度,因为字典需要密钥的哈希值,但仍然慢了10倍。。然而不过我还是很期待。
var allCombinations = new Dictionary<IdById, int>();
foreach (var thisObj in allObjects)
{
foreach (var otherObj in allObjects)
{
var ids = new IdById(thisObj.Id, otherObj.Id);
allCombinations[ids] = (ids.Id1 == ids.Id2 ? 0 : 100);
}
}
foreach (var myObj in myDependency.Objects)
{
foreach (var otherObj in myMatchingObjects)
{
if (myObj.Id != otherObj.Id)
{
var ids = new IdById(myObj.Id, otherObj.Id);
var existingValue = allCombinations[ids];
var minValue =
allCombinations[new IdById(myObj.Id, myDependency.FromObjectId)] +
allCombinations[new IdById(myDependency.ToObjectId, otherObj.Id)] +
myDependency.MinValue;
var maxValue =
allCombinations[new IdById(myObj.Id, myDependency.ToObjectId)] +
allCombinations[new IdById(myDependency.FromObjectId, otherObj.Id)] -
myDependency.MaxValue;
allCombinations[ids] =
Math.Max(Math.Max(existingValue, minValue), maxValue);
}
}
}
for (int i = 0; i < allObjects.Count; i++)
{
//new property to record the index in the array
allObjects[i].Index = i;
}
var allCombinations = new int[allObjects.Count, allObjects.Count];
foreach (var thisObj in allObjects)
{
foreach (var otherObj in allObjects)
{
allCombinations[thisObj.Index, otherObj.Index] = (thisObj.Id == otherObj.Id ? 0 : 100);
}
}
void DoUpdates(int[,] allCombinations)
{
.
.
foreach (var myObject in myDependency.Objects)
{
foreach (var otherObject in myMatchingObjects)
{
.
.
var existingValue = allCombinations[myObject.Index, otherObject.Index];
.
.