Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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++ D与C的解释++;性能差异_C++_D - Fatal编程技术网

C++ D与C的解释++;性能差异

C++ D与C的解释++;性能差异,c++,d,C++,D,D中的简单示例: import std.stdio, std.conv, core.memory; class Foo{ int x; this(int _x){x=_x;} } void main(string args[]) { GC.disable(); int n = to!int(args[1]); Foo[] m= new Foo[n]; for(int i=0;i<n;i++){ m[i] = new Foo(i);

D中的简单示例:

import std.stdio, std.conv, core.memory;

class Foo{
    int x;
    this(int _x){x=_x;}
}

void main(string args[]) {
    GC.disable();
    int n = to!int(args[1]);
    Foo[] m= new Foo[n];
    for(int i=0;i<n;i++){
    m[i] = new Foo(i);
    }
}
< C++ >(GCC)中的注解实例:运行:

为什么??这样一个简单的例子,和这么大的差别:2.54秒和0.52秒。

试试这个:

import std.stdio, std.conv, core.memory;

class Foo{
    int x = void;
    this(in int _x){x=_x;}
}

void main(string args[]) {
    GC.disable();
    int n = to!int(args[1]);
    Foo[] m= new Foo[n];
    foreach(i; 0..n){
    m[i] = new Foo(i);
    }
}

您主要测量三个差异:

  • gcc和dmd生成的代码之间的差异
  • D使用GC分配所需的额外时间
  • 分配一个类所需的额外时间
  • 现在,您可能认为第2点是无效的,因为您使用了
    GC.disable(),但这样做只是为了使GC不会像正常情况下那样进行收集。它不会使GC完全消失,并自动将所有内存分配重定向到C的malloc。它仍然必须做它通常做的大部分事情,以确保GC知道分配的内存以及所有需要时间的事情。通常,这是程序执行的一个相对不重要的部分(甚至忽略地面军事系统提供的好处)。然而,您的基准测试使其成为整个程序的一部分,从而夸大了这种效果

    因此,我建议你考虑一下你的方法的两个变化:

  • 或者切换到使用gdc与gcc进行比较,或者切换到dmc与dmd进行比较
  • 使程序更加等效。要么有D和C++都在堆上分配结构,要么至少使D在不接触GC的情况下分配。如果您正在优化程序以获得最大速度,那么不管使用何种语言,您都将使用structs和C的malloc
  • 我甚至推荐第三个改变:既然您对最高性能感兴趣,那么您应该尝试提出一个完全更好的程序。为什么不切换到结构并将它们连续地定位在内存中?这将使分配(本质上是整个计划)尽可能快

    在我的机器上使用dmd和dmc运行上述代码会导致以下情况:

    • DMC 8.42n(无标志):~880ms
    • DMD 2.062(无标志):~1300ms
    将代码修改为以下内容:

    C++代码:

    #include <cstdlib>
    using namespace std;
    class Foo{
    public:
        int x;
        Foo(int _x);
    
    };
    
    Foo::Foo(int _x){
        x = _x;
    }
    
    int main(int argc, char** argv) {
        int n = atoi(argv[1]);
        Foo** gx = new Foo*[n];
        for(int i=0;i<n;i++){
            gx[i] = new Foo(i);
        }
        return 0;
    }
    
    #include <cstdlib>
    struct Foo {
        int x;
    };
    
    int main(int argc, char** argv) {
        int n = atoi(argv[1]);
        Foo* gx = (Foo*) malloc(n * sizeof(Foo));
        for(int i = 0; i < n; i++) {
            gx[i].x = i;
        }
        free(gx);
        return 0;
    }
    
    使用DMD和DMC使用我的代码会导致以下情况:

    • DMC 8.42n(无标志):~95ms+-20ms
    • DMD 2.062(无标志):~95ms+-20ms
    本质上是相同的(我必须开始使用一些统计数据,让你更好地了解哪一个速度更快,但在这个尺度上,这是无关紧要的)。请注意,使用这种方法比单纯的方法快得多,而且D同样能够使用这种策略。在这种情况下,运行时的差异可以忽略不计,但我们保留了使用GC的好处,而且在编写D代码时可能出错的事情肯定要少得多(请注意,您的程序如何未能
    删除其所有分配?)


    此外,如果您完全愿意,D允许您通过
    import std.C.stdlib使用C的标准库您没有提供太多信息。例如,您甚至不显示您使用的C++程序或如何编译它。如果您没有提供必要的信息,任何人应该如何给出有用的答案?如果没有提供两个完整的程序、编译标志和编译器版本,任何性能比较都是毫无意义的。请尝试测量:void main(string args[]){GC.disable();}并从数字中减去。还要确保编译标志和优化处于一个值得尊敬的比较位置。哇,这个问题投了7票反对票?这有点极端。@GMan在编辑之前看一下原始问题。buildin
    foreach(i,ref foo;m){foo=new foo(i);}
    会更快,因为即使在调试模式下,编译器也可以优化数组的边界检查。边界检查的开销不是可以忽略不计的吗,与内存分配相比,你的胃相当聪明。发帖后我测试了很多东西(使用
    emplace
    之类的东西)。我正在考虑做一个编辑来展示一些结果,但它会让文章变得荒谬地长,而不会给整体结论增加太多。重点仍然是,更好的程序才是真正的解决方案(因为这两种语言的速度都快得多),而D基本上同样能够创建更好的程序。OP的程序没有让我相信在这种情况下继承和单独的堆分配是必要的。实际上,最大的区别是GCC和DMC(它将差异从400%缩小到50%左右,正如我上面的时间与OP的帖子相比所见)。但是对于剩下的部分,GC并不重要,重要的是在D中分配一个类的额外时间。当然,在基类D中还有更多的事情要做。
    import std.stdio, std.conv, core.memory;
    
    class Foo{
        int x = void;
        this(in int _x){x=_x;}
    }
    
    void main(string args[]) {
        GC.disable();
        int n = to!int(args[1]);
        Foo[] m= new Foo[n];
        foreach(i; 0..n){
        m[i] = new Foo(i);
        }
    }
    
    #include <cstdlib>
    struct Foo {
        int x;
    };
    
    int main(int argc, char** argv) {
        int n = atoi(argv[1]);
        Foo* gx = (Foo*) malloc(n * sizeof(Foo));
        for(int i = 0; i < n; i++) {
            gx[i].x = i;
        }
        free(gx);
        return 0;
    }
    
    import std.conv;
    struct Foo{
        int x;
    }
    
    void main(string args[]) {
        int n = to!int(args[1]);
        Foo[] m = new Foo[](n);
        foreach(i, ref e; m) {
            e.x = i;
        }
    }