Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.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#固定数组-哪种结构读取速度最快?_C#_Arrays_Multidimensional Array_Processing Efficiency - Fatal编程技术网

c#固定数组-哪种结构读取速度最快?

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#中使用

我有一些2D数据元素的大数组。A和B的尺寸不相等

A) 在5到20之间

B) 在1000到100000之间

初始化时间没有问题,因为它只是用于实时应用程序的查找表,所以从已知值A和B索引元素的性能是至关重要的。存储的数据当前为单字节值

我在考虑这些解决方案:

byte[A][B] datalist1a;

或者,可能是因为我知道固定大小,所以松开多维,然后在查找它之前将值乘以

byte[A*Bmax + B] datalist3;

我需要知道的是,当我有这个设置时,在C#中使用什么样的数据类型/数组结构进行最有效的查找

编辑1 前两个解决方案应该是多维的,而不是多数组

编辑2 每次查找时都会读取最小维度中的所有数据,但较大维度的数据一次只用于索引一次

因此,这就像从样本B中获取所有A一样。

对于“哪个X更快”(对于所有X而言)唯一有用的答案是:您必须进行反映您需求的性能测试

记住要考虑,一般来说:

  • 程序的维护。如果这不是一个快速的解决方案,那么在大多数情况下,稍微慢一点但可维护的程序是一个更好的选择
  • 微观基准可能具有欺骗性。例如,仅从集合中读取的紧密循环可能会以实际工作完成时不可能的方式进行优化
另外,考虑到你需要查看完整的程序来决定在哪里进行优化。将循环速度提高1%可能对该循环很有用,但如果它只占整个运行时的1%,则不会产生太大的差异



*但所有的规则都有例外。

可能是你最好的方法,那就是使用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]
    )是安全代码中随机访问的最快方法
  • 通常情况下,不安全代码在所有情况下都是最快的(前提是您不重复地锁定它)

在大多数现代计算机上,算术运算远远快于内存查找。 如果您获取的内存地址不在缓存中,或者无序执行从错误的位置拉入,您看到的是10-100个时钟,那么流水线乘法是1个时钟。 另一个问题是缓存局部性。 字节[BAmax+A]数据列表4;如果您是按顺序访问A,则似乎是最佳选择。 当访问datalist4[bAmax+a]时,计算机通常会开始拉入datalist4[bAmax+a+64/sizeof(dataListType)]+128 ... etc,或者如果检测到反向迭代,则datalist4[bAmax+a-64/sizeof(dataListType)]

希望有帮助

可能是德
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();
    }
}