将阵列的一系列位置归零的最快方法?

时间:2017-12-07 22:50:31

标签: c arrays performance

我有一个数组,我希望将零分配给给定范围内的所有位置(在这种情况下,位置10到24)。我这样做:

ulong st[25];
...
for(int i = 10; i < 25; ++i) st[i] = 0x00UL;

这是最快的方法吗?似乎应该有一个没有循环的更快的方式,因为它在内存中是一个连续的位置,但我不知道那会是什么(也许与自己的内存空间异或?如果是这样,如何我会这样做吗?)

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我很想用你所做的简单循环来编写它,并将优化技巧留给编译器。

如果您对编译器做得很好有任何疑问,请检查生成的程序集。

根据经验,程序员比计算机更贵。所以保持便宜的维护;即尽可能写清楚代码。

答案 1 :(得分:1)

您可以使用memset()http://man7.org/linux/man-pages/man3/memset.3.html

虽然可能是同样的事情。

答案 2 :(得分:1)

memset可以完成这项工作。 参见其中14个元素归零的说明性示例。

#include <stdio.h>
#include <string.h> // for memset

void print_array(unsigned long *array, int len)
{
    int i;
    for (i = 0; i<len; i++ )
    {
         printf("%lu ", array[i]);
    };

    printf("\n");   
}

int main()
{
     unsigned long st[25];

    // initialize all elements in the table (25 of them)
    for(int i = 0; i < 25; ++i) 
        st[i] = i;

    // Assign zeroes from position 10 to position 24 (14 zeroes)
    // Note: The last position of the st[] table is not zeroed on purpose!

    // remember of the type of the array `sizeof(unsigned long)`:
    memset( st+10, 0, 14*sizeof(unsigned long) );

    print_array(st, 25);

    return 0;
}

输出:

0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 

两种情况的汇编x86-64 gcc 7.2(无优化!):

int main()
{
    unsigned long st[25];
    memset( st+10, 0, 15*sizeof(unsigned long) );
    return 0;
}

  main:
  push rbp
  mov rbp, rsp
  sub rsp, 208
  lea rax, [rbp-208]
  add rax, 80
  mov edx, 120
  mov esi, 0
  mov rdi, rax
  call memset
  mov eax, 0
  leave
  ret


int main()
{
    unsigned long st[25];
    for(int i = 10; i < 25; ++i) st[i] = 0;
    return 0;
}  
  main:
  push rbp
  mov rbp, rsp
  sub rsp, 88
  mov DWORD PTR [rbp-4], 10
.L3:
  cmp DWORD PTR [rbp-4], 24
  jg .L2
  mov eax, DWORD PTR [rbp-4]
  cdqe
  mov QWORD PTR [rbp-208+rax*8], 0
  add DWORD PTR [rbp-4], 1
  jmp .L3
.L2:
  mov eax, 0
  leave
  ret