C# int[,]数组与Dictionary的效率<&燃气轮机;持续更新

C# int[,]数组与Dictionary的效率<&燃气轮机;持续更新,c#,.net,arrays,performance,unity3d,C#,.net,Arrays,Performance,Unity3d,我在C#中创建了一个Unity中的游戏空间(这只是稍微相关),它表面上是.NET,因为它是Unity中的。游戏空间是二维的,通过细胞自动机生成,并通过细化方法使游戏空间的形状“可用于”我的意图 目前,有关基本游戏空间(活细胞或死细胞、开放或封闭、通道或墙)的数据以二进制值存储在int[,]数组中。最终,附加数据也将存储在数组中,或者可能存储在映射回该int[,]数组的辅助集合中 附加数据将包括以下信息:玩家是否访问过此牢房,玩家当前是否能看到此牢房(LoS),此牢房中是否有敌人或物体/物品 很明

我在C#中创建了一个Unity中的游戏空间(这只是稍微相关),它表面上是.NET,因为它是Unity中的。游戏空间是二维的,通过细胞自动机生成,并通过细化方法使游戏空间的形状“可用于”我的意图

目前,有关基本游戏空间(活细胞或死细胞、开放或封闭、通道或墙)的数据以二进制值存储在
int[,]
数组中。最终,附加数据也将存储在数组中,或者可能存储在映射回该
int[,]
数组的辅助集合中

附加数据将包括以下信息:玩家是否访问过此牢房,玩家当前是否能看到此牢房(LoS),此牢房中是否有敌人或物体/物品

很明显,当玩家导航和敌人沿着他们的路径移动时,视距、视距和敌人数据将是动态的

我希望从一开始就考虑到性能,因为早期的失误可能会导致以后的性能瓶颈,这可能需要进行重大重构——在项目接近尾声时浪费宝贵的开发时间

我的问题是:

更新一个或多个阵列以跟踪数据是否会以线性或指数方式消耗资源?换句话说,如果mapA是[80,80],mapB是[160160],那么mapB将消耗大约4倍的维护资源,还是更多或更少的资源?如果大小超过某个值
int[,]
,使用字典或自定义集合之类的东西是否有好处

我最初的想法是使用类似于
字典的东西。我在一个实用工具中广泛使用字典来维护工作,但是性能是我不考虑的,因为它是内部的,而且非常具体,所以我一般都不太熟悉<>代码>字典<代码>的性能。与具有不同数据的同一网格的多个数组相比,字典的好处是,我可以拥有有意义的键,而不仅仅是需要跟踪的附加值。但是,我怀疑,从长远来看,数组可能会更快,但可读性较差

谢谢

根据,字典在内部是一个结构数组。因此,您需要添加一个额外的层,而不仅仅是将它们单独存储在多维数组中。如果你在寻找微优化,那么你永远无法通过在上面堆积更多的东西来击败阵列

另外,
int[,]
至少有助于提高可读性,因为它准确地表示了数据的视觉显示方式。因此,首先,确保在进行优化之前需要进行优化。优先考虑可读性,而不是过早的优化


对于您正在做的事情,我将坚持使用
int[,]
。它将具有更好的性能和可读性。

< > >强>更新:如注释中指出的,int [],在C++中看起来与C++ [INT][]中有很大的不同,正如我所假设的,我把答案作为参考。因此,当性能不受影响时,您应该始终更喜欢可读性,请使用int[,],而不是我下面建议的内容

我还想补充一点,使用简单的int[]表示二维区域可能更有效。您可以通过以下方式轻松完成:

int[] myArray = new int[width * height];

int x, y; // suppose you want to reach the cell at (x, y) coordinates
int cell = myArray[x + y * width];

for(int i=0 ; i<myArray.Length ; ++i) // suppose you want to iterate through the array
{
    int x = i % width;
    int y = i / width; // be sure that width is an int here, we want the auto-flooring

    int cell = myArray[x + y * width] // like above ;)

    int cell = myArray[i] // or of course for simplicity
}
int[]myArray=newint[width*height];
int x,y;//假设您希望到达(x,y)坐标处的单元格
int cell=myArray[x+y*宽度];

对于(int i=0;i ),它可能取决于播放空间的大小以及它的稀疏程度,但我会考虑使用字典或其他托管结构。 如果你有一个1000x1000的游戏空间,并且你使用了一个数组,它将生成1000000个数组单元,即使你只“访问”了其中的10%。字典方法将使用一个内部数组,但它只会在需要时增长,并且开始时会相当小。比如说10x10(不确定,需要检查)


我假设访问空间的百分比可能大大低于100%。字典将保持较小的内存占用,直到它需要更大,并且当它变大时,字典的开销可以忽略不计。

好吧,我将对这两种类型都进行一些测试。在真实场景中,获取计时器并查找它们的运行时间我会消费。这样说:我已经在2x2的正方形中存储了4个类似大小的盒子。我现在想在4x4的正方形中存储上述盒子中的16个。增加了多少?在任何情况下:记住性能没有错,但我强烈要求首先考虑可理解性和可维护性。然后看看你是否真的有性能p首先是一个问题。然后看看你可以在哪里改进。一个以二维int数组为键的字典,以及字符串-字符串对的字典听起来不像是你以后会真正喜欢调试的东西。回到黑暗时代,当我还是一名学生时,当我们谈论程序优化时,我有一位教授告诉我们:“在开发过程中,不要这样做。在程序运行后,还不要这样做。”诚然,要获得最佳性能需要进行大量重构,但在你弄清楚程序在哪里花费时间之前,你很难知道要优化什么。而在你有了工作代码之前,你无法做到这一点。@TonyVitabile:然后下一步:性能的提高真的值得可读性的损失吗(这通常是随之而来的)@JesseWilliams:一般来说,在计算中是这样的。为x个项目保留空间需要x个空间。为4x个项目保留空间需要4x个空间。如果在所述空间中处理数据需要花费同样多的成本,则完全取决于您使用的算法。对x[0,1]的索引访问速度与x[875232]一样快,搜索性能也会提高(例如)总是会随着时间的增加而恶化