首页 > 解决方案 > 在嵌套 for 循环内部和外部声明整数迭代器之间使用的内存差异

问题描述

代码 1:

int solution(vector<vector<int>>& arr){
    int ans, m = arr.size(), n = arr[0].size(); // it is given that m is atleast 1
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            // do something
            // i and j are only used for iterating over the array
        }
    }
    return ans;
}

代码 2:

int solution(vector<vector<int>>& arr){
    int i, j, ans, m = arr.size(), n = arr[0].size();
    for(i = 0; i < m; i++){
        for(j = 0; j < n; j++){
            // do something
        }
    }
    return ans;
}

我认为 code2 使用较少的内存,因为 code1j在 for 循环m时间中声明了变量(正如评论和答案中提到的那样,这不是真的)。但是当我看到在线编码平台上的许多编码员更喜欢使用 code1 而不是 code2 时,我感到怀疑。

我很欣赏关于这两个代码使用的内存差异的任何解释。

标签: c++memory-managementinteger

解决方案


正如Andreas Brunnet建议的那样,我尝试编译这两个代码,godbolt.org并且如前所述,这两个代码HolyBlackCat的汇编代码是相同的。这是使用的代码和相应的汇编代码(编译器选项是x86-64 gcc 11.2)。

代码:

#include <vector>
int sum(std::vector<std::vector<int>> arr) {
    int i, j, ans = 0, m = arr.size(), n = arr[0].size(); // i, j deleted in code2
    for(i = 0; i < m; i++){ // int i = 0 in code2
        for(j = 0; j < n; j++){ // int j = 0 in code2
            ans += arr[i][j];
        }
    }
    return ans;
}

两个代码的汇编代码是:

sum(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >):
        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        mov     QWORD PTR [rbp-40], rdi
        mov     DWORD PTR [rbp-12], 0
        mov     rax, QWORD PTR [rbp-40]
        mov     rdi, rax
        call    std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::size() const
        mov     DWORD PTR [rbp-16], eax
        mov     rax, QWORD PTR [rbp-40]
        mov     esi, 0
        mov     rdi, rax
        call    std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::operator[](unsigned long)
        mov     rdi, rax
        call    std::vector<int, std::allocator<int> >::size() const
        mov     DWORD PTR [rbp-20], eax
        mov     DWORD PTR [rbp-4], 0
        jmp     .L2
.L5:
        mov     DWORD PTR [rbp-8], 0
        jmp     .L3
.L4:
        mov     eax, DWORD PTR [rbp-4]
        movsx   rdx, eax
        mov     rax, QWORD PTR [rbp-40]
        mov     rsi, rdx
        mov     rdi, rax
        call    std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::operator[](unsigned long)
        mov     rdx, rax
        mov     eax, DWORD PTR [rbp-8]
        cdqe
        mov     rsi, rax
        mov     rdi, rdx
        call    std::vector<int, std::allocator<int> >::operator[](unsigned long)
        mov     eax, DWORD PTR [rax]
        add     DWORD PTR [rbp-12], eax
        add     DWORD PTR [rbp-8], 1
.L3:
        mov     eax, DWORD PTR [rbp-8]
        cmp     eax, DWORD PTR [rbp-20]
        jl      .L4
        add     DWORD PTR [rbp-4], 1
.L2:
        mov     eax, DWORD PTR [rbp-4]
        cmp     eax, DWORD PTR [rbp-16]
        jl      .L5
        mov     eax, DWORD PTR [rbp-12]
        leave
        ret

据我了解,汇编代码中的第 18、19、43、45、46、47 行对应于 c++ 代码的第 5 行,第 21、22、38、40、41、42 行对应于第 6 行(如果我是,请纠正我错误的)。IE

18:        mov     DWORD PTR [rbp-4], 0
19:        jmp     .L2
43:        add     DWORD PTR [rbp-4], 1
44:.L2:
45:        mov     eax, DWORD PTR [rbp-4]
46:        cmp     eax, DWORD PTR [rbp-16]
47:        jl      .L5

for((int) i = 0; i < m; i++)和的对应代码

20:.L5:
21:        mov     DWORD PTR [rbp-8], 0
22:        jmp     .L3
38:        add     DWORD PTR [rbp-8], 1
39:.L3:
40:        mov     eax, DWORD PTR [rbp-8]
41:        cmp     eax, DWORD PTR [rbp-20]
42:        jl      .L4

相当于for((int) j = 0; j < n; j++)

显然,编译器j在两个代码中都只分配了一个寄存器。所以,使用的内存是一样的。


推荐阅读