Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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型数组的等价性 我听到很多人说C++在所有方面都比C快,但是更干净,更漂亮。p> 虽然我不反对C++非常优雅,而且速度很快的事实,但我没有找到任何关键内存访问或处理器绑定应用程序的替代。p> 问题< /强>:C型数组在性能方面是否存在等价于C++?< /P>_C++_C_Performance_Optimization - Fatal编程技术网

C++;C型数组的等价性 我听到很多人说C++在所有方面都比C快,但是更干净,更漂亮。p> 虽然我不反对C++非常优雅,而且速度很快的事实,但我没有找到任何关键内存访问或处理器绑定应用程序的替代。p> 问题< /强>:C型数组在性能方面是否存在等价于C++?< /P>

C++;C型数组的等价性 我听到很多人说C++在所有方面都比C快,但是更干净,更漂亮。p> 虽然我不反对C++非常优雅,而且速度很快的事实,但我没有找到任何关键内存访问或处理器绑定应用程序的替代。p> 问题< /强>:C型数组在性能方面是否存在等价于C++?< /P>,c++,c,performance,optimization,C++,C,Performance,Optimization,下面的例子是人为设计的,但我对解决现实问题感兴趣:我开发了图像处理应用程序,那里的像素处理量很大 double t; // C++ std::vector<int> v; v.resize(1000000,1); int i, j, count = 0, size = v.size(); t = (double)getTickCount(); for(j=0;j<1000;j++) { count = 0; for(i=0;i<size;i++)

下面的例子是人为设计的,但我对解决现实问题感兴趣:我开发了图像处理应用程序,那里的像素处理量很大

double t;

// C++ 
std::vector<int> v;
v.resize(1000000,1);
int i, j, count = 0, size = v.size();

t = (double)getTickCount();

for(j=0;j<1000;j++)
{
    count = 0;
    for(i=0;i<size;i++)
         count += v[i];     
}

t = ((double)getTickCount() - t)/getTickFrequency();
std::cout << "(C++) For loop time [s]: " << t/1.0 << std::endl;
std::cout << count << std::endl;

// C-style

#define ARR_SIZE 1000000

int* arr = (int*)malloc( ARR_SIZE * sizeof(int) );

int ci, cj, ccount = 0, csize = ARR_SIZE;

for(ci=0;ci<csize;ci++)
    arr[ci] = 1;

t = (double)getTickCount();

for(cj=0;cj<1000;cj++)
{
    ccount = 0;
    for(ci=0;ci<csize;ci++)
        ccount += arr[ci];      
}

free(arr);

t = ((double)getTickCount() - t)/getTickFrequency();
std::cout << "(C) For loop time [s]: " << t/1.0 << std::endl;
std::cout << ccount << std::endl;
注意:
getTickCount()
来自第三方库。如果您想测试,只需替换为您最喜欢的时钟测量值

更新:


我使用VS 2010,发布模式,其他默认的

< P>动态大小数组的C++等价物是<代码> STD::向量< /代码>。一个固定大小的数组的C++等价物将是“代码> STD::数组< /COD>或<代码> STD:::Tr1::数组< /COD>前C ++ 11。 如果向量代码没有重新调整大小,很难看出它比使用动态分配的C数组慢多少,前提是编译时启用了一些优化

注意:按照发布的方式运行代码,在x86上的GCC4.4.3上编译,编译器选项

g++-Wall-Wextra-pedanticerrors-O2-std=c++0x

结果重复地接近

(C++)循环时间[us]:507888

一百万

(C) 循环时间[美国]:496659

一百万


因此,在少量试验后,
std::vector
变体似乎慢了约2%。我会考虑这个兼容的性能。

你指出的是,访问对象总是会有一点开销,所以访问<代码>向量不会比访问一个好的旧数组快。

但是即使使用数组是“C时尚”,它仍然是C++,所以不会是问题。


然后,正如@juanchopanza所说,在C++11中有
std::array
,它可能比
std::vector
更有效,但专门用于固定大小的数组。

简单回答:您的基准测试有缺陷

较长的答案:你需要打开全优化以获得C++的性能优势。然而,你的基准仍然有缺陷

一些意见:

  • 如果启用完全优化,将删除大量for循环。这使你的基准变得毫无意义
  • std::vector
    有动态重新分配的开销,请尝试
    std::array

    具体来说,默认情况下,microsoft的stl具有
  • <> LI>没有阻止C++ C/C++代码/基准代码交叉排序的障碍。
  • (不太相关)
    cout通常编译器会做所有的优化。。。你只需要选择一个好的编译器,这似乎是一个编译器的问题。对于C数组,编译器检测模式,使用自动矢量化并发出SSE指令。对于vector来说,它似乎缺乏必要的智能

    如果我强制编译器不使用SSE,结果非常相似(使用
    g++-mno mmx-mno SSE-msoft float-O3测试):

    下面是生成此输出的代码。它基本上是您问题中的代码,但没有任何浮点

    #include <iostream>
    #include <vector>
    #include <sys/time.h>
    
    using namespace std;
    
    long getTickCount()
    {
        struct timeval tv;
        gettimeofday(&tv, NULL);
        return tv.tv_sec * 1000000 + tv.tv_usec;
    }
    
    int main() {
    long t;
    
    // C++ 
    std::vector<int> v;
    v.resize(1000000,1);
    int i, j, count = 0, size = v.size();
    
    t = getTickCount();
    
    for(j=0;j<1000;j++)
    {
        count = 0;
        for(i=0;i<size;i++)
             count += v[i];     
    }
    
    t = getTickCount() - t;
    std::cout << "(C++) For loop time [us]: " << t << std::endl;
    std::cout << count << std::endl;
    
    // C-style
    
    #define ARR_SIZE 1000000
    
    int* arr = new int[ARR_SIZE];
    
    int ci, cj, ccount = 0, csize = ARR_SIZE;
    
    for(ci=0;ci<csize;ci++)
        arr[ci] = 1;
    
    t = getTickCount();
    
    for(cj=0;cj<1000;cj++)
    {
        ccount = 0;
        for(ci=0;ci<csize;ci++)
            ccount += arr[ci];      
    }
    
    delete arr;
    
    t = getTickCount() - t;
    std::cout << "(C) For loop time [us]: " << t << std::endl;
    std::cout << ccount << std::endl;
    }
    
    #包括
    #包括
    #包括
    使用名称空间std;
    long getTickCount()
    {
    结构时间值电视;
    gettimeofday(&tv,NULL);
    返回tv.tv_sec*1000000+tv.tv_usec;
    }
    int main(){
    长t;
    //C++
    std::向量v;
    v、 调整大小(1000000,1);
    int i,j,count=0,size=v.size();
    t=getTickCount();
    对于(j=0;j
    问题:C++中的C样式数组在性能方面是否有等价关系?

    < >回答:编写C++代码!了解你的语言,了解你的标准库并使用它。标准算法是正确的、可读的和快速的(他们知道如何在当前编译器上实现它是最好的)。 在Ubuntu上使用
    g++-O3-std=c++0x
    4.6.3版编译


    <>你的代码我的输出和你的相似。U.S.P.22136给出了一个很好的答案。……<…>我怀疑你做了一个完全优化C++ C++的构建。这个代码中没有指针数组…我只是测试了这个(用一个计算机,用一个特定的编译器稍微修改了代码)。没有优化,“C++风格”。一个比C风格慢三分之一,优化后,“C++风格”一个总是比C样式快一点(而且都比没有优化快)。我在机器上的C++和C++版本都得到了215秒。(GCC和G+在X8664机器上)。(.534/.605)使用g++-O3编译时,两个版本的运行时相同。向量初始化后,分析就会开始,所以这不会是问题…从零开始调整大小可能与分配没有什么不同。@DavidSchwartz可能,但它似乎不必要,并且是对std::vector不太了解的一个标志…但是它比较慢,那么现在呢我需要一些测试,以证明它实际上是比较慢的。运行我自己的版本,用GCC 4.6和4.8编译的代码,我得到了C和C++版本的相同性能。“有STD::在C++ 11中的数组,它比STD::vector更有效。”你能备份这个吗?如果你对一个向量执行改变其大小的操作,比如循环
    推回
    而不调整
    大小
    数组
    可能更有效,例如,因为
    向量
    涉及额外的间接级别(它包含一个指向数据的指针,而
    array
    包含数据)。是的,编译器会将该数据指针的读取提升到循环之外,但这样做需要一个寄存器(将其存储在内存中),而对
    std::array
    的访问可以直接基于堆栈指针。使用一个寄存器是一个次要的性能
    ######### jump to the loop end
        jg  .LBB0_11
    .LBB0_3:                                # %..split_crit_edge
    .Ltmp2:
    # print the benchmark result
        movl    $0, 12(%esp)
        movl    $25, 8(%esp)
        movl    $.L.str, 4(%esp)
        movl    std::cout, (%esp)
        calll   std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
    .Ltmp3:
    # BB#4:                                 # %_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc.exit
    .Ltmp4:
        movl    std::cout, (%esp)
        calll   std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
    .Ltmp5:
    # BB#5:                                 # %_ZNSolsEd.exit
        movl    %eax, %ecx
        movl    %ecx, 28(%esp)          # 4-byte Spill
        movl    (%ecx), %eax
        movl    -24(%eax), %eax
        movl    240(%eax,%ecx), %ebp
        testl   %ebp, %ebp
        jne .LBB0_7
    # BB#6:
    .Ltmp52:
        calll   std::__throw_bad_cast()
    .Ltmp53:
    .LBB0_7:                                # %.noexc41
        cmpb    $0, 28(%ebp)
        je  .LBB0_15
    # BB#8:
        movb    39(%ebp), %al
        jmp .LBB0_21
        .align  16, 0x90
    .LBB0_9:                                #   Parent Loop BB0_11 Depth=1
                                            # =>  This Inner Loop Header: Depth=2
        addl    (%edi,%edx,4), %ebx
        addl    $1, %edx
        adcl    $0, %esi
        cmpl    %ecx, %edx
        jne .LBB0_9
    # BB#10:                                #   in Loop: Header=BB0_11 Depth=1
        incl    %eax
        cmpl    $1000, %eax             # imm = 0x3E8
    ######### jump back to the print benchmark code
        je  .LBB0_3
    
    std::vector<int> v;
    v.resize(1000000,1);
    int i, j, count = 0, size = v.size();
    
    for(j=0;j<1000;j++)
    {
        count = 0;
        for(i=0;i<size;i++)
             count += v[i];     
    }
    
    std::cout << "(C++) For loop time [s]: " << t/1.0 << std::endl;
    std::cout << count << std::endl;
    
    (C++) For loop time [us]: 604610
    1000000
    (C) For loop time [us]: 601493
    1000000
    
    #include <iostream>
    #include <vector>
    #include <sys/time.h>
    
    using namespace std;
    
    long getTickCount()
    {
        struct timeval tv;
        gettimeofday(&tv, NULL);
        return tv.tv_sec * 1000000 + tv.tv_usec;
    }
    
    int main() {
    long t;
    
    // C++ 
    std::vector<int> v;
    v.resize(1000000,1);
    int i, j, count = 0, size = v.size();
    
    t = getTickCount();
    
    for(j=0;j<1000;j++)
    {
        count = 0;
        for(i=0;i<size;i++)
             count += v[i];     
    }
    
    t = getTickCount() - t;
    std::cout << "(C++) For loop time [us]: " << t << std::endl;
    std::cout << count << std::endl;
    
    // C-style
    
    #define ARR_SIZE 1000000
    
    int* arr = new int[ARR_SIZE];
    
    int ci, cj, ccount = 0, csize = ARR_SIZE;
    
    for(ci=0;ci<csize;ci++)
        arr[ci] = 1;
    
    t = getTickCount();
    
    for(cj=0;cj<1000;cj++)
    {
        ccount = 0;
        for(ci=0;ci<csize;ci++)
            ccount += arr[ci];      
    }
    
    delete arr;
    
    t = getTickCount() - t;
    std::cout << "(C) For loop time [us]: " << t << std::endl;
    std::cout << ccount << std::endl;
    }
    
    void testC()
    {
        // unchanged
    }
    
    void testCpp()
    {
        // unchanged initialization
    
        for(j=0;j<1000;j++)
        {
            // how a C++ programmer accumulates:
            count = std::accumulate(begin(v), end(v), 0);    
        }
    
        // unchanged output
    }
    
    int main()
    {
        testC();
        testCpp();
    }
    
    (C) For loop time [ms]: 434.373
    1000000
    (C++) For loop time [ms]: 419.79
    1000000