当一个变量超出范围之前就知道不需要它时,是否应该使用动态内存分配?
例如在以下函数中:
void func(){
int i =56;
//do something with i, i is not needed past this point
for(int t; t<1000000; t++){
//code
}
}
假设一个函数的一小部分只需要 i ,是否值得删除 i 因为它在很长的 for 循环中不需要?
当一个变量超出范围之前就知道不需要它时,是否应该使用动态内存分配?
例如在以下函数中:
void func(){
int i =56;
//do something with i, i is not needed past this point
for(int t; t<1000000; t++){
//code
}
}
假设一个函数的一小部分只需要 i ,是否值得删除 i 因为它在很长的 for 循环中不需要?
正如 Borgleader 所说:
A)这是微优化(很可能是过早的)优化,这意味着不用担心。B)在这种特殊情况下,动态分配甚至可能会损害性能。tl;博士; 先配置,后优化
例如,我将以下两个程序编译为程序集(使用g++ -S
未启用优化的标志)。
i
在堆栈上创建:
int main(void)
{
int i = 56;
i += 5;
for(int t = 0; t<1000; t++) {}
return 0;
}
动态:
int main(void)
{
int* i = new int(56);
*i += 5;
delete i;
for(int t = 0; t<1000; t++) {}
return 0;
}
第一个程序编译为:
movl $56, -8(%rbp) # Store 56 on stack (int i = 56)
addl $5, -8(%rbp) # Add 5 to i (i += 5)
movl $0, -4(%rbp) # Initialize loop index (int t = 0)
jmp .L2 # Begin loop (goto .L2.)
.L3:
addl $1, -4(%rbp) # Increment index (t++)
.L2:
cmpl $999, -4(%rbp) # Check loop condition (t<1000)
setle %al
testb %al, %al
jne .L3 # If (t<1000) goto .L3.
movl $0, %eax # return 0
第二个:
subq $16, %rsp # Allocate memory (new)
movl $4, %edi
call _Znwm
movl $56, (%rax) # Store 56 in *i
movq %rax, -16(%rbp)
movq -16(%rbp), %rax # Add 5
movl (%rax), %eax
leal 5(%rax), %edx
movq -16(%rbp), %rax
movl %edx, (%rax)
movq -16(%rbp), %rax # Free memory (delete)
movq %rax, %rdi
call _ZdlPv
movl $0, -4(%rbp) # Initialize loop index (int t = 0)
jmp .L2 # Begin loop (goto .L2.)
.L3:
addl $1, -4(%rbp) # Increment index (t++)
.L2:
cmpl $999, -4(%rbp) # Check loop condition (t<1000)
setle %al
testb %al, %al
jne .L3 # If (t<1000) goto .L3.
movl $0, %eax # return 0
在上面的汇编输出中,您可以看到正在执行的命令数量之间存在显着差异。如果我在打开优化的情况下编译相同的程序。第一个程序产生了结果:
xorl %eax, %eax # Equivalent to return 0;
第二个产生:
movl $4, %edi
call _Znwm
movl $61, (%rax) # A smart compiler knows 56+5 = 61
movq %rax, %rdi
call _ZdlPv
xorl %eax, %eax
addq $8, %rsp
通过优化,编译器成为改进代码的非常强大的工具,在某些情况下,它甚至可以检测到程序只返回 0 并删除所有不必要的代码。当您在上面的代码中使用动态内存时,程序仍然需要请求然后释放动态内存,它无法优化它。