改变/访问矩阵元素的最佳/最快方法

时间:2014-04-29 15:51:18

标签: c# arrays performance matrix

我对C#很陌生,我对我们的数组,数组数组,锯齿状数组,矩阵和东西都很困难。它与C ++完全不同,因为我无法使用指针和东西来获取矩阵行的引用(除非我使用不安全的代码)。

无论如何,这就是问题:我有一个名为“Image”的结构/类,它包含1024列和768行。对于每一行/列,都有一个包含3个字节的'pixel'结构/类。我想尽可能快地在矩阵的随机位置获取/设置像素。

让我假装我有一个25像素的矩阵。这是5行5列,如下所示:

A B C D E
F G H I J
K L M N O
P Q R S T 
U V X W Y

我需要将M与H和R进行比较。然后M到L和N.然后我需要'求和'G + H + I + L + M + N + Q + R + S.

我该怎么做?

的可能性: 1)创建像像素[5] [5](这是一个锯齿状的数组,对吗?),每当我尝试比较不同列上的元素时,它会很慢,对吗? 2)创建像pixel [25]这样的东西,它不会像编码/准备好那样容易,因为我需要做一些(简单的)数学运算以及我想要访问元素的所有东西 3)创建像pixe [5,5]这样的东西(这是一个多维数组,对吗?)...但我不知道它将如何转换为实际内存...如果它将是一个单独的块记忆,像像素[25],或什么......

因为我打算对每个图像执行此操作('随机'和/不同行/列中元素的比较)数万次。我有1000多张图片。代码优化是必须的.​​.....遗憾的是我不确定应该使用哪种结构/ classe。

TL; DR:什么是最快的,并且在(固定大小)矩阵的随机位置获取/设置元素的EASIEST(编码方式)是什么?

编辑:我不想将C ++与C#进行比较。我只是说我是C#的新手,我想找到使用C#实现这一目标的最佳方法。请不要告诉我回到C ++。

3 个答案:

答案 0 :(得分:1)

我曾在C#中开展基于像素的图像处理。我发现列表中的模式#2最快。为了速度,您必须忘记通过某种漂亮的抽象接口访问像素。像素处理例程必须明确处理图像的宽度和高度。这通常会产生糟糕的代码,但除非Microsoft改进了C#编译器,否则我们会坚持使用这种方法。

如果for循环从数组的索引0开始,并以array.Length - 1结束,编译器将优化数组索引边界测试。这很不错,但通常在处理时必须一次使用多个像素。

答案 1 :(得分:1)

我刚刚完成测试,结果是:

SD Array Test1: 00:00:00.9388379
SD Array Test2: 00:00:00.4117926
MD Array Test1: 00:00:01.4977765
MD Array Test2: 00:00:00.8950093
Jagged Array Test1: 00:00:03.6850013
Jagged Array Test2: 00:00:00.5036041

结论:单维阵列是要走的路......可悲的是,我们失去了可读性。

以下是代码:

    int[] myArray = new int[10000 * 10000];

    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            myArray[(i*10000)+j] = i+j;
        }
    }



    Stopwatch sw = new Stopwatch();
    int sum = 0;

    sw.Start();
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            sum += myArray[(j * 10000) + i];
        }
    }
    sw.Stop();

    Console.WriteLine("SD Array Test1: " + sw.Elapsed.ToString());
    sum=0;

    sw.Restart();
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            sum += myArray[(i * 10000) + j];
        }
    }
    sw.Stop();

    Console.WriteLine("SD Array Test2: " + sw.Elapsed.ToString());

    myArray = null;

    int[,] MDA = new int[10000, 10000];
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            MDA[i, j] = i + j;
        }
    }

    sum = 0;
    sw.Restart();
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            sum += MDA[j, i];
        }
    }
    sw.Stop();
    Console.WriteLine("MD Array Test1: " + sw.Elapsed.ToString());

    sw.Restart();
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            sum += MDA[i, j];
        }
    }
    sw.Stop();
    Console.WriteLine("MD Array Test2: " + sw.Elapsed.ToString());
    MDA = null;

    int[][] JA = new int[10000][];
    for (int i = 0; i < 10000; i++)
    {
        JA[i] = new int[10000];
    }
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            JA[i][j] = i + j;
        }
    }

    sum = 0;
    sw.Restart();
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            sum += JA[j][i];
        }
    }
    sw.Stop();
    Console.WriteLine("Jagged Array Test1: " + sw.Elapsed.ToString());

    sw.Restart();
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            sum += JA[i][j];
        }
    }
    sw.Stop();
    Console.WriteLine("Jagged Array Test2: " + sw.Elapsed.ToString());
    MDA = null;

    Console.ReadKey();

答案 2 :(得分:0)

pixel[5][5]这样的固定二维数组应该足够快。如果您认为对此数据结构的访问时间太慢,那么您应该考虑转移到另一种语言,如c或c ++。