C ++参考变量与其他变量的速度差

时间:2019-03-15 12:28:28

标签: c++ reference

如果我使用参考变量

int &ret = buffer[balance];

在解决在线判断问题时,不会发生超时(限制:2s)。

当我使用常规变量时,

int ret = buffer[balance];

发生超时,我想知道为什么。

这是我的使用引用变量的代码

#define INF 123456789

int coins[100]; // 사용가능한 동전들
int n; // 동전 가짓수
int k; // 총 합

int buffer[10001]; // 금액에 맞는 최소값

int check(int balance) {
    if (balance < 0)
        return INF;

    if (balance == 0)
        return 0;

    int &ret = buffer[balance];

    if (ret != -1)
        return ret;

    ret = INF;

    // 가능한 모든 코인에 대해서 반복
    for (int i = 0; i < n; i++) {
        ret = min(check(balance - coins[i]) + 1, ret);
    }

    return ret;
}

int main() {
    // initialization
    memset(buffer, -1, sizeof(buffer));

    cin >> n >> k;

    for (int i = 0; i < n; i++) {
        scanf_s("%d", &coins[i]);
    }

    int ret = check(k);

    if (ret == 0 || ret == INF)
        ret = -1;
    cout << ret << endl;

    return 0;
    }

使用通用变量

int check(int balance) {
    if (balance < 0)
        return INF;

    if (balance == 0)
        return 0;

    int ret = buffer[balance];

    if (ret != -1)
        return buffer[balance];

    ret = INF;

    // 가능한 모든 코인에 대해서 반복
    for (int i = 0; i < n; i++) {
        ret = min(check(balance - coins[i]) + 1, ret);
    }

    if(ret < INF)
        buffer[balance] = ret;

    return ret;
}

int main() {
    // initialization
    memset(buffer, -1, sizeof(buffer));

    cin >> n >> k;

    for (int i = 0; i < n; i++) {
        scanf("%d", &coins[i]);
    }

    int ret = check(k);

    if (ret == 0 || ret == INF)
        ret = -1;
    cout << ret << endl;

    return 0;
}

这是使用参考的反汇编代码

    int &ret = buffer[balance];
000B1B4B  mov         eax,dword ptr [balance]  
000B1B4E  lea         ecx,buffer (0BB2D0h)[eax*4]  
000B1B55  mov         dword ptr [ret],ecx  

    if (ret != -1)
000B1B58  mov         eax,dword ptr [ret]  
000B1B5B  cmp         dword ptr [eax],0FFFFFFFFh  
000B1B5E  je          check+5Ch (0B1B6Ch)  
        return buffer[balance];
000B1B60  mov         eax,dword ptr [balance]  
000B1B63  mov         eax,dword ptr buffer (0BB2D0h)[eax*4]  
000B1B6A  jmp         check+0C2h (0B1BD2h)  

    ret = INF;
000B1B6C  mov         eax,dword ptr [ret]  
000B1B6F  mov         dword ptr [eax],75BCD15h  

    // 가능한 모든 코인에 대해서 반복
    for (int i = 0; i < n; i++) {
000B1B75  mov         dword ptr [ebp-14h],0  
000B1B7C  jmp         check+77h (0B1B87h)  
000B1B7E  mov         eax,dword ptr [ebp-14h]  
000B1B81  add         eax,1  
000B1B84  mov         dword ptr [ebp-14h],eax  
000B1B87  mov         eax,dword ptr [ebp-14h]  
000B1B8A  cmp         eax,dword ptr [n (0BB2C8h)]  
000B1B90  jge         check+0BDh (0B1BCDh)  
        ret = min(check(balance - coins[i]) + 1, ret);
000B1B92  mov         eax,dword ptr [ebp-14h]  
000B1B95  mov         ecx,dword ptr [balance]  
000B1B98  sub         ecx,dword ptr coins (0BB138h)[eax*4]  
000B1B9F  push        ecx  
000B1BA0  call        check (0B1393h)  
000B1BA5  add         esp,4  
000B1BA8  add         eax,1  
        ret = min(check(balance - coins[i]) + 1, ret);
000B1BAB  mov         dword ptr [ebp-0E0h],eax  
000B1BB1  mov         edx,dword ptr [ret]  
000B1BB4  push        edx  
000B1BB5  lea         eax,[ebp-0E0h]  
000B1BBB  push        eax  
000B1BBC  call        std::min<int> (0B12FDh)  
000B1BC1  add         esp,8  
000B1BC4  mov         ecx,dword ptr [ret]  
000B1BC7  mov         edx,dword ptr [eax]  
000B1BC9  mov         dword ptr [ecx],edx  
    }
000B1BCB  jmp         check+6Eh (0B1B7Eh)  

    return ret;
000B1BCD  mov         eax,dword ptr [ret]  
000B1BD0  mov         eax,dword ptr [eax]  
}

使用通用变量

    int ret = buffer[balance];
00EF1B52  mov         eax,dword ptr [balance]  
00EF1B55  mov         ecx,dword ptr buffer (0EFB2D0h)[eax*4]  
00EF1B5C  mov         dword ptr [ret],ecx  

    if (ret != -1)
00EF1B5F  cmp         dword ptr [ret],0FFFFFFFFh  
00EF1B63  je          check+61h (0EF1B71h)  
        return buffer[balance];
00EF1B65  mov         eax,dword ptr [balance]  
00EF1B68  mov         eax,dword ptr buffer (0EFB2D0h)[eax*4]  
00EF1B6F  jmp         check+0C1h (0EF1BD1h)  

    ret = INF;
00EF1B71  mov         dword ptr [ret],75BCD15h  

    // 가능한 모든 코인에 대해서 반복
    for (int i = 0; i < n; i++) {
00EF1B78  mov         dword ptr [ebp-18h],0  
00EF1B7F  jmp         check+7Ah (0EF1B8Ah)  
00EF1B81  mov         eax,dword ptr [ebp-18h]  
00EF1B84  add         eax,1  
00EF1B87  mov         dword ptr [ebp-18h],eax  
00EF1B8A  mov         eax,dword ptr [ebp-18h]  
00EF1B8D  cmp         eax,dword ptr [n (0EFB2C8h)]  
00EF1B93  jge         check+0BEh (0EF1BCEh)  
        ret = min(check(balance - coins[i]) + 1, ret);
00EF1B95  mov         eax,dword ptr [ebp-18h]  
00EF1B98  mov         ecx,dword ptr [balance]  
00EF1B9B  sub         ecx,dword ptr coins (0EFB138h)[eax*4]  
00EF1BA2  push        ecx  
00EF1BA3  call        check (0EF1393h)  
00EF1BA8  add         esp,4  
        ret = min(check(balance - coins[i]) + 1, ret);
00EF1BAB  add         eax,1  
00EF1BAE  mov         dword ptr [ebp-0E4h],eax  
00EF1BB4  lea         edx,[ret]  
00EF1BB7  push        edx  
00EF1BB8  lea         eax,[ebp-0E4h]  
00EF1BBE  push        eax  
00EF1BBF  call        std::min<int> (0EF12FDh)  
00EF1BC4  add         esp,8  
00EF1BC7  mov         ecx,dword ptr [eax]  
00EF1BC9  mov         dword ptr [ret],ecx  
    }
00EF1BCC  jmp         check+71h (0EF1B81h)  

    return ret;
00EF1BCE  mov         eax,dword ptr [ret]  
}

感谢您的阅读。请帮助我!

2 个答案:

答案 0 :(得分:0)

ret是引用时,您正在通过引用修改数组,并且代码等效于

int check(int balance) {
    if (balance < 0)
        return INF;

    if (balance == 0)
        return 0;

    if (buffer[balance] != -1)
        return buffer[balance];

    buffer[balance] = INF;

    for (int i = 0; i < n; i++) {
        buffer[balance] = min(check(balance - coins[i]) + 1, buffer[balance]);
    }

    return buffer[balance];
}

如果ret不是引用,则永远不会更新数组,因此ret != -1永远不会为真。

答案 1 :(得分:0)

使用引用时,将使用相同的堆对象。
我快速得出结论,让您了解参考的外观: Referanes

如果您想了解更多信息,请阅读这篇文章:Ref and Pointers