c#固定数组-哪种结构读取速度最快?
我有一些2D数据元素的大数组。A和B的尺寸不相等 A) 在5到20之间 B) 在1000到100000之间 初始化时间没有问题,因为它只是用于实时应用程序的查找表,所以从已知值A和B索引元素的性能是至关重要的。存储的数据当前为单字节值 我在考虑这些解决方案:c#固定数组-哪种结构读取速度最快?,c#,arrays,multidimensional-array,processing-efficiency,C#,Arrays,Multidimensional Array,Processing Efficiency,我有一些2D数据元素的大数组。A和B的尺寸不相等 A) 在5到20之间 B) 在1000到100000之间 初始化时间没有问题,因为它只是用于实时应用程序的查找表,所以从已知值A和B索引元素的性能是至关重要的。存储的数据当前为单字节值 我在考虑这些解决方案: byte[A][B] datalist1a; 或 或 或 或者,可能是因为我知道固定大小,所以松开多维,然后在查找它之前将值乘以 byte[A*Bmax + B] datalist3; 或 我需要知道的是,当我有这个设置时,在C#中使用
byte[A][B] datalist1a;
或
或
或
或者,可能是因为我知道固定大小,所以松开多维,然后在查找它之前将值乘以
byte[A*Bmax + B] datalist3;
或
我需要知道的是,当我有这个设置时,在C#中使用什么样的数据类型/数组结构进行最有效的查找
编辑1
前两个解决方案应该是多维的,而不是多数组
编辑2
每次查找时都会读取最小维度中的所有数据,但较大维度的数据一次只用于索引一次
因此,这就像从样本B中获取所有A一样。对于“哪个X更快”(对于所有X而言)唯一有用的答案是:您必须进行反映您需求的性能测试
记住要考虑,一般来说:
- 程序的维护。如果这不是一个快速的解决方案,那么在大多数情况下,稍微慢一点但可维护的程序是一个更好的选择
- 微观基准可能具有欺骗性。例如,仅从集合中读取的紧密循环可能会以实际工作完成时不可能的方式进行优化
*但所有的规则都有例外。可能是你最好的方法,那就是使用HashMap
?除非Amax或Bmax是2的幂,否则我会赌锯齿阵列 我这么说是因为交错数组需要两个索引访问,因此速度非常快。其他形式暗示乘法,隐式或显式。除非乘法是一个简单的移位,否则我认为它可能比几个索引访问要重一些 编辑:以下是用于测试的小程序:
class Program
{
private static int A = 10;
private static int B = 100;
private static byte[] _linear;
private static byte[,] _square;
private static byte[][] _jagged;
unsafe static void Main(string[] args)
{
//init arrays
_linear = new byte[A * B];
_square = new byte[A, B];
_jagged = new byte[A][];
for (int i = 0; i < A; i++)
_jagged[i] = new byte[B];
//set-up the params
var sw = new Stopwatch();
byte b;
const int N = 100000;
//one-dim array (buffer)
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _linear[r * B + c];
}
}
}
sw.Stop();
Console.WriteLine("linear={0}", sw.ElapsedMilliseconds);
//two-dim array
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _square[r, c];
}
}
}
sw.Stop();
Console.WriteLine("square={0}", sw.ElapsedMilliseconds);
//jagged array
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _jagged[r][c];
}
}
}
sw.Stop();
Console.WriteLine("jagged={0}", sw.ElapsedMilliseconds);
//one-dim array within unsafe access (and context)
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
fixed (byte* offset = &_linear[r * B])
{
for (int c = 0; c < B; c++)
{
b = *(byte*)(offset + c);
}
}
}
}
sw.Stop();
Console.WriteLine("unsafe={0}", sw.ElapsedMilliseconds);
Console.Write("Press any key...");
Console.ReadKey();
Console.WriteLine();
}
}
类程序
{
专用静态INTA=10;
私有静态int B=100;
专用静态字节[]_线性;
专用静态字节[,]_平方;
专用静态字节[][].\u交错;
不安全的静态void Main(字符串[]args)
{
//初始化数组
_线性=新字节[A*B];
_平方=新字节[A,B];
_锯齿=新字节[A][];
for(int i=0;i
- 多维(
)数组几乎总是最慢的,除非在重随机访问场景下。理论上不应该这样,但这是CLR的一个奇怪之处[,]
- 锯齿状数组(
)几乎总是比多维数组快;即使在随机访问的情况下。它们有内存开销[][]
- 一维(
)和代数数组([]
)是安全代码中随机访问的最快方法[y*stride+x]
- 通常情况下,不安全代码在所有情况下都是最快的(前提是您不重复地锁定它)
byte[B,A] datalist2b;
byte[A*Bmax + B] datalist3;
byte[B*Amax + A] datalist4;
class Program
{
private static int A = 10;
private static int B = 100;
private static byte[] _linear;
private static byte[,] _square;
private static byte[][] _jagged;
unsafe static void Main(string[] args)
{
//init arrays
_linear = new byte[A * B];
_square = new byte[A, B];
_jagged = new byte[A][];
for (int i = 0; i < A; i++)
_jagged[i] = new byte[B];
//set-up the params
var sw = new Stopwatch();
byte b;
const int N = 100000;
//one-dim array (buffer)
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _linear[r * B + c];
}
}
}
sw.Stop();
Console.WriteLine("linear={0}", sw.ElapsedMilliseconds);
//two-dim array
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _square[r, c];
}
}
}
sw.Stop();
Console.WriteLine("square={0}", sw.ElapsedMilliseconds);
//jagged array
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _jagged[r][c];
}
}
}
sw.Stop();
Console.WriteLine("jagged={0}", sw.ElapsedMilliseconds);
//one-dim array within unsafe access (and context)
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
fixed (byte* offset = &_linear[r * B])
{
for (int c = 0; c < B; c++)
{
b = *(byte*)(offset + c);
}
}
}
}
sw.Stop();
Console.WriteLine("unsafe={0}", sw.ElapsedMilliseconds);
Console.Write("Press any key...");
Console.ReadKey();
Console.WriteLine();
}
}