免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: alazer
打印 上一主题 下一主题

[C] 在函数中频繁定义大的数组会不会影响速度? [复制链接]

论坛徽章:
0
31 [报告]
发表于 2008-01-11 11:13 |只看该作者
原帖由 pzz68 于 2008-1-10 22:11 发表


写在循环内并不是每次循环都重新分配数据空间的. 两个情况对变量 t 分配次数是一样的, 都是一次.

不是一样的,放在循环体内,每循环一次就会分配和释放一次. 写个class在看看在析构方法中打印提示信息,测试一下就知道了.

论坛徽章:
0
32 [报告]
发表于 2008-01-11 11:14 |只看该作者
原帖由 杨二 于 2008-1-11 03:02 发表


反对, 变量用时才定义是基本原则。效率的事情留给编译器。
不能做这种优化的编译器在这个时代有点说不过去了

不存在你说的优化问题, 两种写法是有不同的语法含义的.请看23楼.

论坛徽章:
0
33 [报告]
发表于 2008-01-11 12:41 |只看该作者
原帖由 converse 于 2008-1-10 11:35 发表
我一般尽量避免编写这种频繁分配变量空间的代码,比如说

一个循环中
for()
{
    data t = XXX;
}

我写为:
data t;
for()
{
   t = XXX;
}


原帖由 pzz68 于 2008-1-10 22:11 发表


写在循环内并不是每次循环都重新分配数据空间的. 两个情况对变量 t 分配次数是一样的, 都是一次.


原帖由 zszyj 于 2008-1-11 11:13 发表

不是一样的,放在循环体内,每循环一次就会分配和释放一次. 写个class在看看在析构方法中打印提示信息,测试一下就知道了.


一样的,都只分配一次,看看这个:

#include <stdio.h>

void main( void )
{
        int i;
        printf("&i = %d\n\n", &i);
        for(i=0; i<3; i++)
        {
                int  t = i;
                printf("&t = %d, t = %d\n", &t, t);
        }

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

        int  m;
        printf("\n&m = %d\n", &m);
        int  n;
        printf("&n = %d\n", &n);
}


执行结果:

&i = 1245052

&t = 1245048, t = 0
&t = 1245048, t = 1
&t = 1245048, t = 2

&k = 1245044, k = 0
&k = 1245044, k = 1
&k = 1245044, k = 2

&m = 1245040
&n = 1245036

论坛徽章:
0
34 [报告]
发表于 2008-01-11 13:12 |只看该作者
converse  的例子没有举对,但是大致上是这么个意思,可以理解。

for(n)
{
  int data = 0;
}
分配只做一次,赋值会做n次。
for(n)
{
  class data;
}
内存分配也只有一次,但是构造和析构函数会做n次。
编译原理的代码优化有讲到这个问题(好像蛮经典的,好几本书都有)。例如前面的int data=1,如果data值在循环中没有改变,则int data=1会被提取到循环外面。

论坛徽章:
0
35 [报告]
发表于 2008-01-11 13:56 |只看该作者
这绝对是恶劣的编程习惯,压栈出栈都是几十k的数据量,虽然内存拷贝快,但还是有成本的

写个内存池呗~

论坛徽章:
0
36 [报告]
发表于 2008-01-11 14:19 |只看该作者
只是栈指针里面的值赋大一点而已?

论坛徽章:
0
37 [报告]
发表于 2008-01-11 15:02 |只看该作者
在堆上分配内存我们知道比较耗时,因为它是动态的。栈上内存虽然可以定义后直接使用,但它也存在内容覆盖的问题,因为你这次这个数组的栈内指针很有可能和上次的不同。所以不断的定义新数组即使没有栈溢出,也会影响速度。(不知道我理解的对不对,还请多指教:))

论坛徽章:
0
38 [报告]
发表于 2008-01-12 12:24 |只看该作者
原帖由 zszyj 于 2008-1-11 11:13 发表

不是一样的,放在循环体内,每循环一次就会分配和释放一次. 写个class在看看在析构方法中打印提示信息,测试一下就知道了.

原帖由 dxcnjupt 于 2008-1-11 13:12 发表
... 构造和析构函数会做n次 ...



你们竟然会认为构造函数分配对象空间,析构函数释放对象空间!

不得不吐一下。。。。。。

论坛徽章:
0
39 [报告]
发表于 2008-01-14 00:58 |只看该作者
原帖由 pzz68 于 2008-1-12 12:24 发表





你们竟然会认为构造函数分配对象空间,析构函数释放对象空间!

不得不吐一下。。。。。。

人家说的是,内存分配也只有一次,但是构造和析构函数会做n次。

论坛徽章:
0
40 [报告]
发表于 2008-01-14 23:14 |只看该作者
这个问题似乎有很多人的理解是不对的
关于在函数内定义的局部变量大家都知道是在栈上的,但是变量空间的分配只会进行一次。
程序在编译的时候,编译器会计算出函数内出现的所有变量的空间总和,然后修改堆栈寄存器的值预留空间,
dxcnjupt兄说的没错,但是dxcnjupt兄太低调了,也不出来为大家解释一下
所谓的为局部变量分配空间其实相当简单,就是调用了sub指令,移动栈顶指针,并且只会在进入函数体的时候执行一次,
以下面的代码为例,“int a;”如果放在了for里面也不会每次循环都为a分配内存空间,在进入函数的时候已经分配好了,
只是变量的作用域稍有不同,还有就是“int b = a;”,即使if的条件不满足未执行该语句,变量b还是要占用栈空间的,
并不是说没有进入if就不会为b分配空间
void Func(int a1, int a2)
{
    int a;
    for (int i=0; i<10; i++)
    {
        a = i;
        if (0 < a1)
        {
            int b = a;
        }
    }
}
个人理解,只为抛砖引玉,大家都来探讨探讨。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP