在性能方面有什么好处?键入[,]或类型[] []?

时间:2008-10-03 21:04:24

标签: c# performance arrays

在C#中使用二维数组(type[,])或数组数组(type[][])会更高效吗?

特别是初始分配和项目访问

4 个答案:

答案 0 :(得分:5)

当然,如果一切都失败了......试试吧!以下给出(在“发布”中,在控制台上):

Size 1000, Repeat 1000
    int[,] set: 3460
    int[,] get: 4036 (chk=1304808064)
    int[][] set: 2441
    int[][] get: 1283 (chk=1304808064)

所以锯齿状阵列更快,至少在这个测试中。有趣!但是,这是一个相对的小因素,所以我仍然会坚持用更好的描述我的要求。除了某些特定(高CPU /处理)方案之外,可读性/可维护性应该优于小的性能增益。但是,由你决定。

请注意,此测试假设您访问阵列的次数比创建时更频繁,因此我没有包含创建时间,除非内存高度分散,否则我期望矩形更快一些

using System;
using System.Diagnostics;
static class Program
{
    static void Main()
    {
        Console.WriteLine("First is just for JIT...");
        Test(10,10);
        Console.WriteLine("Real numbers...");
        Test(1000,1000);

        Console.ReadLine();
    }

    static void Test(int size, int repeat)
    {
        Console.WriteLine("Size {0}, Repeat {1}", size, repeat);
        int[,] rect = new int[size, size];
        int[][] jagged = new int[size][];
        for (int i = 0; i < size; i++)
        { // don't cound this in the metrics...
            jagged[i] = new int[size];
        }
        Stopwatch watch = Stopwatch.StartNew();
        for (int cycle = 0; cycle < repeat; cycle++)
        {
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    rect[i, j] = i * j;
                }
            }
        }
        watch.Stop();
        Console.WriteLine("\tint[,] set: " + watch.ElapsedMilliseconds);

        int sum = 0;
        watch = Stopwatch.StartNew();
        for (int cycle = 0; cycle < repeat; cycle++)
        {
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    sum += rect[i, j];
                }
            }
        }
        watch.Stop();
        Console.WriteLine("\tint[,] get: {0} (chk={1})", watch.ElapsedMilliseconds, sum);

        watch = Stopwatch.StartNew();
        for (int cycle = 0; cycle < repeat; cycle++)
        {
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    jagged[i][j] = i * j;
                }
            }
        }
        watch.Stop();
        Console.WriteLine("\tint[][] set: " + watch.ElapsedMilliseconds);

        sum = 0;
        watch = Stopwatch.StartNew();
        for (int cycle = 0; cycle < repeat; cycle++)
        {
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    sum += jagged[i][j];
                }
            }
        }
        watch.Stop();
        Console.WriteLine("\tint[][] get: {0} (chk={1})", watch.ElapsedMilliseconds, sum);
    }
}

答案 1 :(得分:2)

我相信[,]可以分配一个连续的内存块,而[] []是N + 1个块分配,其中N是第一个维度的大小。所以我猜想[,]在初始分配时会更快。

访问可能大致相同,除了[] []将涉及一个额外的解引用。除非你处于一个特别严密的循环中,否则它可能是一种冲洗。现在,如果您正在执行类似图像处理的操作,您在行之间引用而不是逐行遍历,则引用的位置将起到一个重要因素,[,]可能会边缘[] [ ]取决于您的缓存大小。

正如Marc Gravell所说,用法是评估表现的关键......

答案 2 :(得分:2)

这取决于。 MSDN杂志的文章 Harness the Features of C# to Power Your Scientific Computing Projects 说:

  

虽然矩形阵列在结构和性能方面通常优于锯齿状阵列,但在某些情况下,锯齿状阵列可提供最佳解决方案。如果您的应用程序不需要对数组进行排序,重新排列,分区,稀疏或大,那么您可能会发现锯齿状数组的表现非常好。

答案 3 :(得分:-1)

type [,]会更快。不仅因为偏移计算较少。主要是因为约束检查较少,内存分配较少,内存本地化程度较高。 type [] []不是单个对象 - 它必须分配1 + N个对象,并且彼此远离。