[疑难] 测试D语言多维数组性能

Colorful 2007-05-15
刚刚看到了多维数组的帖子,想起今天刚刚完成的专门用来测试性能的工具类,于是赶紧做了个性能比对。
D语言与C#语言在相同条件的二维数组访问差别还是蛮大的。
D语言我只做了一个很普通的数组访问,因为不确定数组的指针会否移动,所以没做数组的指针测试。
而C#采用二维数组(慢),交错数组(比较慢)以及使用指针访问数组(快)三种情况测试。
测试的结果很有意思。
D在普通情况下,会比C#采用的普通二维数组和交错数组快大概2~3倍。而比C#指针访问慢1倍左右。
各位有兴趣的可以自己写个测试看看结果如何。

PS : D语言写的工具类在dotmars项目里。

C# 指针访问代码如下:
private unsafe void Unsafe2DimArrayAccess(int[,] array)
        {
            int dim0LowIndex = 0;
            int dim0HighIndex = array.GetUpperBound(0);
            int dim1LowIndex = 0;
            int dim1HighIndex = array.GetUpperBound(1);
            int dim0Elements = dim0HighIndex - dim0LowIndex;
            fixed (int* pointer = &array[0, 0])
            {
                for (int i = dim0LowIndex; i <= dim0HighIndex; i++)
                {
                    int baseOfDim = i * dim0Elements;
                    for (int j = dim1LowIndex; j < dim1HighIndex; j++)
                    {
                        int element = pointer[baseOfDim + j];
                    }
                }
            }
        }
Colorful 2007-05-15
目前性能测试只有Win版实现,Linux不熟悉,没办法。
qiezi 2007-05-15
C#的内在不熟悉,看你的例子,C#的二维数组应该是平坦的整块内存吧?D的二维数组不是整块的,但效率差别不应该会这么大。

D数组本质上是一个struct:
struct Array {
    size_t length;
    void*  ptr;
}

每个数组结构自身占用的内存在32位上是8字节,64位上是16字节,这比整块内存访问时使用指针可能性能要差一些,但我猜想你的代码大概是这样的:
char[][] arr2d;
foreach(arr; arr2d)
  // ..处理arr.ptr

因为数组是结构对象,在foreach时会拷贝,所以可能会比指针拷贝慢一倍。改成这样再测试一下:
foreach(ref arr; arr2d)
  // ..处理arr.ptr

dotmars里面的代码还没看,先上班去咯,有时间看看。。
qiezi 2007-05-15
即使是参数传递时多拷贝一倍数据,我觉得应该也不会慢一倍,不知道你的测试程序是什么样的。

D里面写二维数组可能会有CPU cache的问题,由于数据是分散存放,不利于cache。可以自己用一维数组包装成二维数组类测试看看性能。

另外我在linux上测试gdc比dmd编译出来的程序要快很多,有时会有一到两倍之多。
Colorful 2007-05-15
C#数组确实是连续内存分配,这跟C/C++是一致的。
回去之后再好好改一下测试程序,呵呵。
oldrev 2007-05-15
Colorful,TimeSpan 在 dotmars/base/time.d 里已经实现了
Global site tag (gtag.js) - Google Analytics