C++在循环内和循环外定义变量的差异(如何写出高效的for循环)

本文探讨了C++在循环内外定义变量的效率差异。通过测试,发现在主流编译器如GCC中,对于基本数据类型,优化使得在循环内外定义变量并无明显性能区别。然而,当涉及复杂对象时,编译器可能不会优化,循环内多次创建对象会影响效率。最佳实践是在循环外定义变量并避免循环内重复创建对象。
摘要由CSDN通过智能技术生成

写这篇文章的原因是我在问答平台看到的一个问题:

C++内层循环中定义变量和在外面定义比影响大吗?

问题来自:http://ask.csdn.net/questions/176270

例如:
for(int i=0;i<999;i++) {
for(int j=0;j<999;j++);
}

内层循环每次都定义j会造成多大的消耗呢?

此处我给出的回答是:

这个需要看你具体用什么编译器。不过主流编译器(如vs和gcc)这一块优化都比较好,不会反复分配变量。

看到答案和评论,好像有很多人对这个感兴趣,所以我打算给大家实测分享一下,于是写了如下代码进行测试:

#include <cstdio>
using namespace std;

void Test1()
{
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("%d,%d\n", int(i), int(j));
        }
    }

}

void Test2()
{
    int i, j;

    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d,%d\n", int(i), int(j));
        }
    }
}

int main()
{
    Test1();
    Test2();

    return 0;
}

OK,程序非常简单,Test1Test2是两个循环,干相同的事情,就是在双重循环里打印一下 ij 的值,差别只在于一个在循环外定义变量 j,另一个在循环内定义变量 j

此处我使用g++进行编译,优化等级是O0(这是GCC默认的优化等级,也是最低的优化等级)的:

g++ -O0 -g test.cpp

编译后,我将生成的Test1函数和Test2函数反汇编出来,得出的结果是这样的:

Test1函数反汇编如下:

(gdb) disas /m Test1
Dump of assembler code for function Test1():
5       {
   0x0804841d <+0>:     push   %ebp
   0x0804841e <+1>:     mov    %esp,%ebp
   0x08048420 <+3>:     sub    $0x28,%esp

6           for (int i = 0; i < 2; i++)
   0x08048423 <+6>:     movl   $0x0,-0x10(%ebp)
   0x0804842a <+13>:    jmp    0x804845d <Test1()+64>
   0x08048459 <+60>:    addl   $0x1,-0x10(%ebp)
   0x0804845d <+64>:    cmpl   $0x1,-0x10(%ebp)
   0x08048461 <+68>:    jle    0x804842c <Test1()+15>

7           {
8               for (int j = 0; j < 3; j++)
   0x0804842c <+15>:    movl   $0x0,-0xc(%ebp)
   0x08048433 <+22>:    jmp    0x8048453 <Test1()+54>
   0x0804844f <+50>:    addl   $0x1,-0xc(%ebp)
   0x08048453 <+54>:    cmpl   $0x2,-0xc(%ebp)
   0x08048457 <+58>:    jle    0x8048435 <Test1()+24>

9               {
10                  printf("%d,%d\n", int(i), int(j));
   
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值