一个有趣的问题(c语言高手请进)

GhostCoer 2003-12-12 12:01:39
(a):
for (i=0;i<10;i++)
for (j=0;j<10;j++)
a[i][j]=0;
(b):
for (j=0;j<10;j++)
for (i=0;i<10;i++)
a[i][j]=0;
问程序段(a)和(b)哪个的效率更高?为什么?

...全文
20 27 打赏 收藏 举报
写回复
27 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
ehom 2003-12-12
layman2008(eniac)给的是两段代码的反汇编结果,很明显指令基本一样,唯一的一点区别也不影响指令配对~~~效率应该一样

注意看赋值语句,这里就是取地址而已~~~

0040105E mov edx,dword ptr [ebp-4] ;取i的值
00401061 imul edx,edx,28h ;i=i*40,layman2008(eniac)应该是在Win32环境下定义的int,占4字节
00401064 lea eax,[ebp+edx-198h] ;[ebp-198h]取数组的首地址,[ebp+edx-198h]取第i行首地址,198h是408的16进制表示,10*10*4+2*4(2表示i,j占的栈空间)
0040106B mov ecx,dword ptr [ebp-8] ;取j的值
0040106E mov dword ptr [eax+ecx*4],0 ;取a[i][j]的地址
  • 打赏
  • 举报
回复
Edison621 2003-12-12
应该与行优先还是列优先有关
  • 打赏
  • 举报
回复
MooseWOler 2003-12-12
是trace的内容吧
  • 打赏
  • 举报
回复
UEAnswer 2003-12-12
layman2008(eniac) 你用的什么语言写得什么意思??看不懂,能说明一下么?
  • 打赏
  • 举报
回复
cpsoft 2003-12-12
是不是还要看编译器是怎么优化的?
  • 打赏
  • 举报
回复
19830711 2003-12-12
这要先计算机是行优先还是列优先
前者是A,后者是B高
  • 打赏
  • 举报
回复
arfi 2003-12-12
a[i][j] = *(*(a+i)+j)
都得执行加法与取地址运算,我认为效率上没什么区别
  • 打赏
  • 举报
回复
layman2008 2003-12-12
(a)-------
7: for (i=0;i<10;i++)
0040102E mov dword ptr [ebp-4],0
00401035 jmp main+30h (00401040)
00401037 mov eax,dword ptr [ebp-4]
0040103A add eax,1
0040103D mov dword ptr [ebp-4],eax
00401040 cmp dword ptr [ebp-4],0Ah
00401044 jge main+69h (00401079)
8: for (j=0;j<10;j++)
00401046 mov dword ptr [ebp-8],0
0040104D jmp main+48h (00401058)
0040104F mov ecx,dword ptr [ebp-8]
00401052 add ecx,1
00401055 mov dword ptr [ebp-8],ecx
00401058 cmp dword ptr [ebp-8],0Ah
0040105C jge main+67h (00401077)
9: a[i][j]=0;
0040105E mov edx,dword ptr [ebp-4]
00401061 imul edx,edx,28h
00401064 lea eax,[ebp+edx-198h]
0040106B mov ecx,dword ptr [ebp-8]
0040106E mov dword ptr [eax+ecx*4],0
00401075 jmp main+3Fh (0040104f)
00401077 jmp main+27h (00401037)

(b)-------
7: for (j=0;j<10;j++)
0040102E mov dword ptr [ebp-8],0
00401035 jmp main+30h (00401040)
00401037 mov eax,dword ptr [ebp-8]
0040103A add eax,1
0040103D mov dword ptr [ebp-8],eax
00401040 cmp dword ptr [ebp-8],0Ah
00401044 jge main+69h (00401079)
8: for (i=0;i<10;i++)
00401046 mov dword ptr [ebp-4],0
0040104D jmp main+48h (00401058)
0040104F mov ecx,dword ptr [ebp-4]
00401052 add ecx,1
00401055 mov dword ptr [ebp-4],ecx
00401058 cmp dword ptr [ebp-4],0Ah
0040105C jge main+67h (00401077)
9: a[i][j]=0;
0040105E mov edx,dword ptr [ebp-4]
00401061 imul edx,edx,28h
00401064 lea eax,[ebp+edx-198h]
0040106B mov ecx,dword ptr [ebp-8]
0040106E mov dword ptr [eax+ecx*4],0
00401075 jmp main+3Fh (0040104f)
00401077 jmp main+27h (00401037)
  • 打赏
  • 举报
回复
layman2008 2003-12-12
内存中 是这样存储的 a[0][0]a[0][1]...a[1][0]...a[9][9]

所以(a)是连续的给内存赋值
而(b)不是

所以应该是a高
  • 打赏
  • 举报
回复
lbaby 2003-12-12
个人觉得,这个要依据编译器的“聪明”程度而定
如果编译器足够“聪明”
--也就是说,编译器不管是行优先,还是列优先,都能按照最连续的方式访问内存-- 的话,上边的两段代码的效果是一样的

如果仅是和我们看到的c代码一样,
那么,最连续的访问方式将获得最好的时间效果
(由cache 的设计,最连续的访问方式会最大程度的减少cache失误)

  • 打赏
  • 举报
回复
visio 2003-12-12
认为(A)好些
好看些!!!
:)
  • 打赏
  • 举报
回复
mainSean 2003-12-12
觉得还是前一种!
  • 打赏
  • 举报
回复
eureka0891 2003-12-12
呵呵,
用一种方法试试,
把i,j都高为1000000000000;
然后去循环.....
  • 打赏
  • 举报
回复
zhtgong 2003-12-12
效率应该是一样的,时间复杂度是相同的
  • 打赏
  • 举报
回复
november5 2003-12-12
这个...
谁效率高不知道,
还是用memset吧
  • 打赏
  • 举报
回复
wangprince 2003-12-12
应该是a好了。

a对内存使用的更合理,避免了频繁访问。

其实这也要看对内存的管理方法,不过一般都是行优先!
  • 打赏
  • 举报
回复
WYlslrt 2003-12-12
我认为与编译器行优先和列优先有关,因为不同的计算机还要进行取地址如按行优先,那b就先给每列赋值,然后在从新去每行地址再赋值
  • 打赏
  • 举报
回复
ssunwind 2003-12-12
没什么区别 应该一样
  • 打赏
  • 举报
回复
phbzy 2003-12-12
看看他们在内存中是怎么排列的,其中一种肯定使的平凡的跳页(物理页),这种效率底点的
  • 打赏
  • 举报
回复
101monster 2003-12-12
呵呵,为什么不用Memset?这两种都是效率低下的写法。
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C语言
加入

6.6w+

社区成员

C语言相关问题讨论
社区管理员
  • C语言
  • 小灸舞
申请成为版主
帖子事件
创建了帖子
2003-12-12 12:01
社区公告
暂无公告