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

C 将阵列的一系列位置归零的最快方法?,c,arrays,performance,C,Arrays,Performance,我有一个数组,我希望为给定范围内的所有位置(在本例中为位置10到24)分配零。我正在这样做: ulong st[25]; ... for(int i = 10; i < 25; ++i) st[i] = 0x00UL; ulong街[25]; ... 对于(inti=10;i

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

ulong st[25];
...
for(int i = 10; i < 25; ++i) st[i] = 0x00UL;
ulong街[25];
...
对于(inti=10;i<25;++i)st[i]=0x00UL;
这是最快的方法吗?考虑到循环在内存中是一个连续的位置,似乎应该有一种没有循环的更快的方法,但我不知道那会是什么(可能是将内存空间本身XORing?如果是,我将如何做?)

有什么想法吗?

您可以使用
memset()
来实现:

也许在封面下也是一样

您可以使用
memset()


也许在封面下也是一样

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

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


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

我很想像您那样用简单的循环编写代码,并将优化技巧留给编译器

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


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

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;
}
两种情况下的汇编x86-64 gcc 7.2(无优化!):

intmain()
{
未签字的朗街[25];
memset(st+10,0,15*sizeof(无符号长));
返回0;
}
主要内容:
推动rbp
mov rbp,rsp
副秘书长,208
lea rax,[rbp-208]
加上rax,80
mov edx,120
电影esi,0
莫夫尔迪,拉克斯
调用内存集
mov-eax,0
离开
ret
int main()
{
未签字的朗街[25];
对于(inti=10;i<25;++i)st[i]=0;
返回0;
}  
主要内容:
推动rbp
mov rbp,rsp
副区长,88
mov DWORD PTR[rbp-4],10
.L3:
cmp DWORD PTR[rbp-4],24
jg.L2
mov eax,德沃德PTR[rbp-4]
cdqe
mov QWORD PTR[rbp-208+rax*8],0
添加DWORD PTR[rbp-4],1
jmp.L3
.L2:
mov-eax,0
离开
ret

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;
}
两种情况下的汇编x86-64 gcc 7.2(无优化!):

intmain()
{
未签字的朗街[25];
memset(st+10,0,15*sizeof(无符号长));
返回0;
}
主要内容:
推动rbp
mov rbp,rsp
副秘书长,208
lea rax,[rbp-208]
加上rax,80
mov edx,120
电影esi,0
莫夫尔迪,拉克斯
调用内存集
mov-eax,0
离开
ret
int main()
{
未签字的朗街[25];
对于(inti=10;i<25;++i)st[i]=0;
返回0;
}  
主要内容:
推动rbp
mov rbp,rsp
副区长,88
mov DWORD PTR[rbp-4],10
.L3:
cmp DWORD PTR[rbp-4],24
jg.L2
mov eax,德沃德PTR[rbp-4]
cdqe
mov QWORD PTR[rbp-208+rax*8],0
添加DWORD PTR[rbp-4],1
jmp.L3
.L2:
mov-eax,0
离开
ret

memset()
我不会太担心。对我来说,这听起来像是过早的优化。如果你发现事情太慢,那就回头想想吧;它可以实现为一种内置的汇编语言,运行速度更快。你也可以硬编码25个元素的数组(
ulong st[25]={0x00L,0x00L,0x00L…};
@DanFarrell循环从10开始。但是如果他想将整个数组初始化为0,
ulong st[25]={0x00UL}
应该用更少的键入来完成!如果你的编译器没有将其优化到最快的方式来清空处理器上的内存范围,那么你的编译器就不是很好。GCC会做得很好。
memset()
我不会太担心。对我来说,这听起来像是过早的优化。如果你发现事情太过缓慢,那么再来考虑一下;它可以实现为一种内置汇编语言,运行速度更快。你也可以硬编码25个元素的数组(
ulong st[25]={0x00L,0x00L,0x00L…}
@DanFarrell循环从10开始。但是如果他想将整个数组初始化为0,
ulong st[25]={0x00UL}
应该用更少的键入来完成!如果你的编译器没有将其优化到最快的方式来清空处理器上的内存范围,那么你的编译器就不是很好。GCC会做得很好。幻数14是不正确的。
for(int i=10;i<25;++i)st[i]=0x00UL;
zero'd 15个元素。@chux 14是故意使用的。这在代码注释中有说明,以说明最后一个元素是否为零。请参阅输出打印输出。//注意:st[]表不是故意归零的!谢谢!所以说我需要再键入5个字符,所以我正在键入它们。好的。代码比注释更响亮-很容易忽略裸魔法数字的作用。如果OP想要最快的解决方案,为什么不优化代码?启用优化后,两个示例都会得到xor eax,eax/ret。魔法数字14是不正确。
for(int i=10;i<25;++i)st[i]=0x00UL;
zero'd 15个元素。@chux 14是故意使用的。这在代码注释中说明了最后一个元素是否未归零。请参阅输出打印输出。//注意:st的最后位置[]表不是故意归零的!谢谢!所以我说我需要再键入5个字符,所以我正在键入它们。好的。代码比注释更响亮-很容易忽略裸数字的作用。如果OP想要最快的解决方案,为什么不优化代码?启用优化后,两个示例都得到xor eax,eax/ret
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