如何将新数组归零

How to zero a new array?

本文关键字:数组 归零 新数组      更新时间:2023-10-16

1:

int a[100] = {};

阿拉伯数字:

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

3:

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

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

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

2:这很危险,它会在整个数组中复制模式 0。例如,如果数组是浮点数,则不能保证将其表示为零。此外,memset 复制字节而不是逐字复制,如果您传递它不是零的东西,可能会导致各种问题。例如memset(a, 1, ...)会导致它充满16843009。除非使用 C 字符串,否则不应使用 Memset。

3:合法且清晰易读。易于扩展到非零值,而 (1( 不会。虽然更啰嗦。

决定使用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;
}

使用 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(当然允许优化!