0

当一个变量超出范围之前就知道不需要它时,是否应该使用动态内存分配?

例如在以下函数中:

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 循环中不需要?

4

1 回答 1

2

正如 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 并删除所有不必要的代码。当您在上面的代码中使用动态内存时,程序仍然需要请求然后释放动态内存,它无法优化它。

于 2013-08-24T06:30:33.890 回答