代码之家  ›  专栏  ›  技术社区  ›  Edy Bourne

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

  •  0
  • Edy Bourne  · 技术社区  · 8 年前

    我有一个数组,我希望将零分配给给定范围内的所有位置(在本例中是位置10到24)。我正在这样做:

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

    这是最快的方法吗?考虑到循环在内存中是一个连续的位置,似乎应该有一种没有循环的更快的方法,但我不知道那会是什么(可能是将内存空间与自身进行异或运算?如果是这样,我会怎么做?)

    有什么想法吗?

    3 回复  |  直到 8 年前
        1
  •  2
  •   Bathsheba    8 年前

    我很想像您一样使用简单的循环编写它,并将优化技巧留给编译器。

    如果您怀疑编译器做得很好,请检查生成的程序集。

    根据经验,程序员比计算机贵。因此,保持维护成本低廉;i、 e.尽可能写清楚的代码。

        2
  •  1
  •   sg7 Krafty Coder    8 年前

    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
    
        3
  •  1
  •   erik258    8 年前

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

    但在封面下可能也是一样。