几何尺寸与公差论坛

 找回密码
 注册
查看: 8810|回复: 5

效率问题之局部颠覆

[复制链接]
发表于 2008-1-27 22:13:36 | 显示全部楼层 |阅读模式
1,全局变量&局部变量
代码一:
PNT3D P, P1, P2;
for( int i=0; i<3; i++ )
{
   P = P1+P2;
}

代码二:
PNT3D P1, P2;
for( int i=0; i<3; i++ )
{
   PNT3D P = P1+P2;
}

结论:前者比后者多一次PNT3D的构造函数、一次PNT3D的析构函数;

2,返回对象问题
代码一:
PNT2D  operator +(PNT2D& a, PNT2D& b)
{
   PNT2D res;
   res.x = a.x+b.x;
   res.y = a.y+b.y;
   return res;
}

代码二:
PNT2D  operator +(PNT2D& a, PNT2D& b)
{
   PNT2D res(a.x+b.x,a.y+b.y);
   return res;
}

代码三:
PNT2D  operator +(PNT2D& a, PNT2D& b)
{
   return PNT2D(a.x+b.x,a.y+b.y);
}

结论:第二段代码比第一段少做两次附值操作;第三段代码比第二段代码少一次PNT2D的构造函数、一次PNT2D的析构函数;
 楼主| 发表于 2008-1-27 22:13:58 | 显示全部楼层

回复: 效率问题之局部颠覆

3,数组效率

class PNT3D
{
public:
   double x[3];   
};

class PNT3D_2
{
public:
   double x, y, z;
};

Method( PNT3D* p1, PNT3D_2* p2 )
{
   p1->x[2] = 1;  //代码一
   p2->y = 2;     //代码二
}

结论:代码一是否比代码二慢呢?结论是速度相同;
 楼主| 发表于 2008-1-27 22:14:27 | 显示全部楼层

回复: 效率问题之局部颠覆

4,直接返回对象的效率

class PNT100
{
public:  
   PNT100(){}

public
   double x[100];
};

PNT100 GetValue()
{
   return PNT100();
}

void Method()
{
   PNT100 P = GetValue();
}

返回大对象是否效率很低呢?

结论:不低。当函数返回大对象时,编译器会在调用处栈上分配对象内存,然后将指针传递给函数,而并不是函数直接返回对象;
 楼主| 发表于 2008-1-27 22:14:52 | 显示全部楼层

回复: 效率问题之局部颠覆

5,memcpy效率

结论:memcpy与直接赋值的效率临界点为16-18个浮点数

也就是说,当拷贝小于16*8个字节的内存时,赋值快;当拷贝大于18*8个字节内存时,memcpy快;
 楼主| 发表于 2008-1-27 22:16:20 | 显示全部楼层

回复: 效率问题之局部颠覆

主  题:  循环中局部变量是否在每次循环中都重新分配内存?  
作  者:  cxd306021 (逍遥浪子)  
等  级:   
信 誉 值:  97  
所属社区:  C/C++ C++ 语言  
问题点数:  100  
回复次数:  16  
发表时间:  2005-01-25 12:28:58  
   

   
循环中局部变量是否在每次循环中都重新分配内存?
    void func1(void)
      {
        for (int n=2;n<4;n++)
         {
           int result=1;
           result*=n;
         
         }
       }
请 问当n=2时,result=1,result=1*2=2;当n=3时,result=2 还是 result=1?也就是说在循环中局部变量在每次循环中是否都重新分配内存?那位高手能总结一下c/c++中的内存分配理论,也就是哪些需要分配内存, 啥时候分配,啥时候销毁?
  
  回复人: steedhorse(晨星) ( ) 信誉:124  2005-01-25 12:34:00  得分: 0  


   不会的。
栈指针在函数调用时增长,而不是在分配每个变量时分别增长。

但如果是对象,虽然其空间同样不会每次都分配,但其构造函数可能每次都执行——这是C++语法规定的。
  

Top  

回复人: qiaozhiwei(乔) ( ) 信誉:100  2005-01-25 12:34:00  得分: 0  


   没错,result的作用域在for{}之间,每次都会重新赋值
  

Top  

回复人: steedhorse(晨星) ( ) 信誉:124  2005-01-25 12:36:00  得分: 0  


   哦,没说清楚,内存不会重新分配,但“=1”这个初始化动作却每次都会执行。
  

Top  

回复人: yjh1982(血精灵) ( ) 信誉:105  2005-01-25 12:41:00  得分: 0  


   理论上会分配内存.
实际上通常不会.
  

Top  

回复人: suyouxin(为什么划船不用浆) ( ) 信誉:100  2005-01-25 12:52:00  得分: 0  


   是的,这个要看编译器是否优化你的这段代码.
理论上按照你的意思是重新分配栈空间,但具体的还得看编译器
  

Top  

回复人: idler(偶是豆子。。。) ( ) 信誉:104  2005-01-25 12:55:00  得分: 0  


   一个作用域内内存不会重新分配的。
但是构造函数应该会执行。不过也有可能被优化掉。
  

Top  

回复人: daylove(爱晶如梦)(昨夜西风调碧树,独上高楼,望尽天涯路……) ( ) 信誉:100  2005-01-25 12:59:00  得分: 0  


   result重新赋值了。
  

Top  

回复人: alever513(戴帽子的) ( ) 信誉:100  2005-01-25 13:02:00  得分: 0  


   for (int n=2;n<4;n++)
语义分析时为
int n=2;
while(n<4)
{
   n++;
}
所以我认为不会的

  

Top  

回复人: kobefly(科比---不惧挑战!) ( ) 信誉:115  2005-01-25 13:09:00  得分: 0  


   回复人: steedhorse(晨星) ( ) 信誉:124  2005-01-25 12:34:00  得分: 0  


   不会的。
栈指针在函数调用时增长,而不是在分配每个变量时分别增长。

但如果是对象,虽然其空间同样不会每次都分配,但其构造函数可能每次都执行——这是C++语法规定的。
  

不明白,栈指针在分配每个变量时不是分别增长?
我觉得分配变量时会增长啊
请指教!!1

个人同意 yjh1982(血精灵) ( ) 信誉:105  2005-01-25 12:41:00  得分: 0  


   理论上会分配内存.
实际上通常不会.
  这个代码块作用域的变量
理论上是每次都要分配内存的
但由于编译的优化,可能会导致只分配一次。





  

Top  

回复人: qinxiaolin(103+18=521) ( ) 信誉:100  2005-01-25 13:10:00  得分: 0  


   void func1(void)
      {
        for (int n=2;n<4;n++)
         {
           int result=1;
           result*=n;
         
         }
       }

内存不会重新分配,可以跟踪result的地址值;但每次都会执行 result=1;result在for循环结束后,生命周期结束.

  

Top  

回复人: blueskyzsz(青禾) ( ) 信誉:100  2005-01-25 13:11:00  得分: 0  


   void func1(void)
{
for (int n=2;n<4;n++)
{
int result=1;            // 理论上 result 作用域从这里开始
result*=n;

}                        // 到这里结束
}

result 理论上每次都应该重新分配的,不过具体的要看编译器的优化
  

Top  

回复人: justoday(咱地啦? 又让人给煮了) ( ) 信誉:136  2005-01-25 13:14:00  得分: 0  


   调用func1的时候为涵数内的变量分配内存

而不是 运行到 int result=1; 才为 result 分配内存

所以每次循环 不会重新分配内存
  

Top  

回复人: Squall1009(钰枫)(我思故我在) ( ) 信誉:100  2005-01-25 13:15:00  得分: 0  


   感觉应该是会的吧,除非优化
  

Top  

回复人: morris2600(叶知秋) ( ) 信誉:100  2005-01-25 13:17:00  得分: 0  


   同意楼上的观点!
每次循环不会重新分配
  

Top  

回复人: daylove(爱晶如梦)(昨夜西风调碧树,独上高楼,望尽天涯路……) ( ) 信誉:100  2005-01-25 13:31:00  得分: 0  


   应该是不分配内存。
可能这在编译起里,把这个变量定义为寄存器变量了 。
  

Top  

回复人: whoho(在北方流浪) ( ) 信誉:105  2005-01-25 13:31:00  得分: 0  


   for通常速度很快,因为编译器作了很多优化,有时候甚至不需要内存循环变量
编译器直接把它弄成寄存器了
  

Top
 楼主| 发表于 2008-1-27 22:17:05 | 显示全部楼层

回复: 效率问题之局部颠覆

也就是说:
1,单纯的循环内定义局部变量对速度毫无影响
2,循环外定义的对象(有构造和析构函数的对象),有时甚至会影响效率;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-4-26 09:00 , Processed in 0.099373 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表