关于交换两个整数(不借助第三个临时数)... 及 Delphi、VC、Asm 效率对比

ADelphiCoder 2009-11-05 08:22:56
不借助第三个临时数交换两个整数,无外乎进行所谓的数字魔术,或借助寄存器实现,但除此外还有一种“巧妙的”方法:通过 XOR 变换实现——不过论其本质,还是所谓的数字魔术,:-) ...

随手测试了下 数字魔术、借助寄存器(纯 Asm 实现) 及 XOR变换 的效率,耗时显示,纯 Asm 实现 < XOR变换 < 数字魔术——结果当然不出意料,纯Asm实现 比另两者快很多。



Delphi 测试代码:

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils, Windows;

var
I, J, K, M, N: Integer;
begin
// the BASE arithmetic ...
M := 1;
N := 2;

K := GetTickCount;
for I := 0 to 5000 do
begin
for J := 0 to 5000 do
begin
M := M + N;
N := M - N;
M := M - N;
end;
end;
K := GetTickCount - K;
Writeln(K, ';', M, ';', N);
ReadLn;

// use Registers ...
M := 1;
N := 2;

K := GetTickCount;
asm // EAX: 循环计数; ECX: I; EDX: J; EBX: M; EDI: N
PUSH EBX
PUSH EDI
MOV EBX, M
MOV EDI, N

MOV EAX, 5000
MOV ECX, 0
@Loop1: CMP ECX, EAX
JA @Loop1End
MOV EDX, 0
@Loop2: CMP EDX, EAX
JA @Loop2End
XCHG EBX, EDI
INC EDX
JMP @Loop2
@Loop2End: INC ECX
JMP @Loop1

@Loop1End: MOV M, EBX
MOV N, EDI
POP EDI
POP EBX
end;
K := GetTickCount - K;
Writeln(K, ';', M, ';', N);
ReadLn;

// Now XOR ...
M := 1;
N := 2;

K := GetTickCount;
for I := 0 to 5000 do
begin
for J := 0 to 5000 do
begin
M := M xor N;
N := N xor M;
M := M xor N;
end;
end;
K := GetTickCount - K;
Writeln(K, ';', M, ';', N);
ReadLn;
end.



P.S:以 VC 6.0 + SP6 测试了同样效果的代码,Release 下其结果明显快于 Delphi 的数字魔术(但仍比 纯Asm实现 慢一些) ...Delphi 优化器确实较差,没办法。

VC 测试代码:

#include <iostream>
#include <windows.h>

void main()
{
int I, J, K, M, N;

M = 1;
N = 2;
K = GetTickCount();
for (I = 0; I <= 5000; I++)
{
for (J = 0; J <= 5000; J++)
{
M = M + N;
N = M - N;
M = M - N;
}
}
K = GetTickCount() - K;

printf("%d;%d;%d\n", K, M, N);
}



另,关于 Delphi 的优化,盒子里的讨论:
http://bbs.2ccc.com/topic.asp?topicid=336505

一句话:Delphi Compiler 的优化太差了。
...全文
226 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
不得闲 2009-11-07
  • 打赏
  • 举报
回复
晕,这个还要用什么ASM么?
不是相当简单嘛,数字游戏而已
var
a,b: integer;
t: dword;
begin
t := GetTickCount;
a := 3;
b := 5;
a := a + b;
b := a - b;
a := a - b;
ShowMessage('用时:'+inttostr(GetTickCount - t));
ShowMessage(IntToStr(a));
ShowMessage(IntToStr(b));
end;
jadeluo 2009-11-06
  • 打赏
  • 举报
回复
Delphi的程序编译成exe文件后直接运行exe文件再来评测, 否则与VC的Release相比明显不公。
ADelphiCoder 2009-11-06
  • 打赏
  • 举报
回复
to 2L:优化全开、调试信息皆无;

to 4L:Delphi Compiler 编译是快(不全是其编译器的功劳),但编译出来的程序(优化后)执行效率却很不怎么样...(不说 VCL);

to 6L:你可以自己测试下,看结果如何;

to 7L:要不俺去你家蹭饭?俺家穷...

to 9L:看清楚了,都同样是 Console Application,你可以看下 Delphi 的 CPU 窗口,看是否“相当优化”...
咱甚至反汇编过 Delphi 和 VC 的(都是优化全开后生成的)控制台程序,唉,结果相当让人沮丧,Delphi 的优化器不是一般的差。


大家可以自己试试。
jadeluo 2009-11-06
  • 打赏
  • 举报
回复
另外, Delphi的工程选择成Console Application, 就和VC工程的运行结果几乎一致了。

这段代码,Delphi编译器生成的结果是相当优化的,LZ可以在工程中加个断点,然后进入CPU窗看一下编译出的汇编代码。
yct0605 2009-11-06
  • 打赏
  • 举报
回复
UP
xiaowei_001 2009-11-06
  • 打赏
  • 举报
回复
楼主你妈喊你回家吃饭!
贝隆 2009-11-06
  • 打赏
  • 举报
回复
学习
Rex_love_Burger 2009-11-06
  • 打赏
  • 举报
回复
我要买3G手机
wintergoes 2009-11-06
  • 打赏
  • 举报
回复
Delphi能随便把你的代码优化吗
你写个
tmp=a;
a=b;
b=tmp;
他也不知道你是干啥啊

你觉得ASM快,可以嵌进去嘛
wooden954 2009-11-06
  • 打赏
  • 举报
回复
楼主的测试结果看不到!
gwj601 2009-11-06
  • 打赏
  • 举报
回复
参考
imho888 2009-11-06
  • 打赏
  • 举报
回复
纯接分
sparklerl 2009-11-05
  • 打赏
  • 举报
回复
up
iamduo 2009-11-05
  • 打赏
  • 举报
回复
==!

我还一直以为D的编译器是最快的呢。
s11ss 2009-11-05
  • 打赏
  • 举报
回复
有意思
gyk120 2009-11-05
  • 打赏
  • 举报
回复
Delphi编译器可以设置是否进行优化的……
ADelphiCoder 2009-11-05
  • 打赏
  • 举报
回复

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧