如何将新数组归零?

时间:2013-10-11 01:43:31

标签: c++

1

int a[100] = {};

2:

int a[100];
memset(a, 0, sizeof(a));

3:

int a[100];
fill(a, a + 100, 0);

从上面显示的方法中将新数组归零的最佳方法是什么?它们之间有什么区别?

3 个答案:

答案 0 :(得分:4)

1:最好的。它将所有值设置为默认值,大多数值为0。

2:这很危险,它会将模式0复制到整个数组中。例如,如果数组是浮点数,则无法保证它表示为零。 memset也会按字节顺序复制,而不是单词,如果你传递的不是零,会导致各种问题。例如,memset(a, 1, ...)会使其填充16843009。除非使用C字符串,否则不应使用Memset。

3:合法,清晰。易于扩展到非零值,而(1)则不会。虽然更冗长。

答案 1 :(得分:2)

决定使用VS2010进行全面优化来调查性能问题。

有趣的结果:

1:13105

2:13044

3:4546

没有初始化案例:906。

因此,VS2010在案例memset中使用1非常相似,但fill的优化程度更高。

#include "stdafx.h"
#include <Windows.h>
#include <algorithm>
#include <iostream>

int  fref()
{
    int a[1024];
    return a[512] - a[256];
}

int f1()
{
    int a[1024] = {};

    return a[512] - a[256];
}

int  f2()
{
    int a[1024];
    memset(a, 0, sizeof(a));
    return a[512] - a[256];
}



int f3()
{
    int a[1024];
    std::fill(a, a + 100, 0);
    return a[512] - a[256];
}

typedef int (*Function)();

LONGLONG time(Function function)
{
    const unsigned numLoops = 50000;
    LARGE_INTEGER start;
    QueryPerformanceCounter(&start);
    for(unsigned j = 1; j != numLoops; ++j)
    function();
    LARGE_INTEGER end;
    QueryPerformanceCounter(&end);
    return end.QuadPart-start.QuadPart;
}

Function tests[]= 
{
    &fref, &f1, &f2, &f3
};

const unsigned numTests = sizeof(tests)/sizeof(tests[0]);

LONGLONG results[numTests] = {};


int _tmain(int argc, _TCHAR* argv[])
{
    for(unsigned i = 0; i != numTests; ++i)
    {
        results[i] = time(tests[i]);
    }
    for(unsigned i = 0; i != numTests; ++i)
        std::cout << results[i] << std::endl;
    getchar();
    return 0;
}

答案 2 :(得分:1)

使用Keith的示例代码。海湾合作委员会的差异如下:

GCC 4.7.3:g ++ -Wall -Wextra -std = c ++ 0x -O3 -c array-fill.cpp

#include <algorithm>
#include <cstring>

int  fref() {
    int a[1024];
    return a[512] - a[256]; }

int f1() {
    int a[1024] = {};
    return a[512] - a[256]; }

int  f2() {
    int a[1024];
    std::memset(a, 0, sizeof(a));
    return a[512] - a[256]; }

int f3() {
    int a[1024];
    std::fill(a, a + 100, 0);
    return a[512] - a[256]; }

拆卸

objdump -d array-fill.o | C ++ FILT

00000000 <fref()>:
   0:   b8 00 10 00 00          mov    $0x1000,%eax
   5:   e8 00 00 00 00          call   a <fref()+0xa>
   a:   29 c4                   sub    %eax,%esp
   c:   8b 84 24 00 08 00 00    mov    0x800(%esp),%eax
  13:   2b 84 24 00 04 00 00    sub    0x400(%esp),%eax
  1a:   81 c4 00 10 00 00       add    $0x1000,%esp
  20:   c3                      ret
  21:   eb 0d                   jmp    30 <f1()>

00000030 <f1()>:
  30:   31 c0                   xor    %eax,%eax
  32:   c3                      ret
  33:   8d b6 00 00 00 00       lea    0x0(%esi),%esi
  39:   8d bc 27 00 00 00 00    lea    0x0(%edi,%eiz,1),%edi

00000040 <f2()>:
  40:   b8 00 10 00 00          mov    $0x1000,%eax
  45:   e8 00 00 00 00          call   4a <f2()+0xa>
  4a:   29 c4                   sub    %eax,%esp
  4c:   31 c0                   xor    %eax,%eax
  4e:   81 c4 00 10 00 00       add    $0x1000,%esp
  54:   c3                      ret
  55:   8d 74 26 00             lea    0x0(%esi,%eiz,1),%esi
  59:   8d bc 27 00 00 00 00    lea    0x0(%edi,%eiz,1),%edi

00000060 <f3()>:
  60:   b8 00 10 00 00          mov    $0x1000,%eax
  65:   e8 00 00 00 00          call   6a <f3()+0xa>
  6a:   29 c4                   sub    %eax,%esp
  6c:   89 e0                   mov    %esp,%eax
  6e:   8d 94 24 90 01 00 00    lea    0x190(%esp),%edx
  75:   c7 00 00 00 00 00       movl   $0x0,(%eax)
  7b:   83 c0 04                add    $0x4,%eax
  7e:   39 d0                   cmp    %edx,%eax
  80:   75 f3                   jne    75 <f3()+0x15>
  82:   8b 84 24 00 08 00 00    mov    0x800(%esp),%eax
  89:   2b 84 24 00 04 00 00    sub    0x400(%esp),%eax
  90:   81 c4 00 10 00 00       add    $0x1000,%esp
  96:   c3                      ret

在这种情况下,C样式初始化(​​f1)肯定允许优化!