Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 读取2D矩阵的最快方法_C#_Performance_Dictionary_Multidimensional Array_Profiling - Fatal编程技术网

C# 读取2D矩阵的最快方法

C# 读取2D矩阵的最快方法,c#,performance,dictionary,multidimensional-array,profiling,C#,Performance,Dictionary,Multidimensional Array,Profiling,我使用嵌套字典来存储一个2D矩阵,该矩阵在初始化时具有已知值,我发现它太慢,无法读取。还有更快的吗 更新 我不是在寻找我的代码“不工作”的任何原因。它工作正常-但我想知道任何方法,使它更快。下面的详细信息将提供上下文 我还尝试过使用自定义类作为键来展平嵌套字典,但速度更慢 细节 我有一个500-7000个对象的列表,我需要为每个可能的组合(250000-49000000)存储一个值 每个可能的组合都有一个默认值。此值将根据对象之间的依赖关系而更改,每个对象平均有1个依赖关系。对于每个依赖项,将有

我使用嵌套字典来存储一个2D矩阵,该矩阵在初始化时具有已知值,我发现它太慢,无法读取。还有更快的吗

更新 我不是在寻找我的代码“不工作”的任何原因。它工作正常-但我想知道任何方法,使它更快。下面的详细信息将提供上下文

我还尝试过使用自定义类作为键来展平嵌套字典,但速度更慢

细节 我有一个500-7000个对象的列表,我需要为每个可能的组合(250000-49000000)存储一个值

每个可能的组合都有一个默认值。此值将根据对象之间的依赖关系而更改,每个对象平均有1个依赖关系。对于每个依赖项,将有1-100个更新。每次更新平均会读取5次值

例如,我有1700个对象用于2890000个可能的组合,有1900个依赖项,这意味着9500-95000次读取。此示例的计算时间超过90秒

这是初始化代码。我对这个部分很满意,因为它在不到一秒钟的时间内就完成了

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版本,则创建自己的结构)作为键,这样就可以删除第二层字典。@dumetrulo
allObjects
不会更改。不过,每当我查询列表时,我都必须进行某种索引,我会尝试一下。我已经试着用一个类作为键而不是元组来删除第二层字典,但是速度非常慢。我以前没见过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];
            .
            .