没有技术上的原因。
其实delphi/c++ builder不论在动态连接或静态连接的情况下,生成的程序都要比
vc++的小。比如mdi的例子程序:在delphi/c++ builder中选new ... | projects |
mdi application,在vc++中用mdi app wizard;生成的程序功能是非常类似的。
下面是比较结果:
(delphi打开优化,c++ builder使用最大速度优化,vc++ 5使用最小代码优化)
delphi 3 delphi 5 c++ builder 5 vc++ 5
dynamic link 21k 35k 44k 70k
static link 253k 398k 467k 490k
凡是使用了应用类库的程序(不管是mfc,owl,vcl以及新的clx框架)都要比不使用的大
不少。这是因为目前的智能连接(smart link)技术还只能针对全局变量/过程,而不能
用于对象结构。哪怕你只使用了某个类(或被这个类间接引用)的一个属性或方法,这个
类以及它所引用的所有类都全部被连接到exe中。目前所有的编译器都没有解决这个问
题。
(ps: 其实能生成最小代码(真编译)的高级语言编译器是turbo pascal,不信你写程序
比较一下:
program test;
begin
writeln('hello, world.');
end.
生成的exe不到1.5k。而同样的c程序:
#include
main()
{
printf("hello, world.\n");
}
最精悍的c/c++编译器生成的代码也有6k。
)
那么几个编译器生成的代码质量又如何呢?
举一个例子,比如我们在编程时经常用到的for循环语句:
(1) object pascal:
procedure foo;
var
i, j: integer;
begin
for i := 0 to 15 do j := j + i;
end;
(2) c++
void foo(void)
{
int i, j;
for (i = 0; i < 16; i++) j = j + i;
}
delphi 3生成的代码(打开优化): 字节数 时钟周期
00424aa9 33c0 xor eax,eax 1
00424aab 40 inc eax 1
00424aac 83f810 cmp eax,0x10 1
00424aaf 75fa jnz -0x06 0 (可并行)
-----------------
8 3
c++ builder 5生成的代码(最大速度优化):
00401535 33c0 xor eax,eax 1
00401537 40 inc eax 1
00401538 83f810 cmp eax,0x10 1
0040153b 7cfa jl -0x06 0 (可并行)
-----------------
8 3
visual c++ 5生成的代码(最大速度优化):
27: for (i = 0; i < 16; i ++)
00401205 mov ecx,dowrd ptr [j] 1
00401208 xor eax,eax 0 (可并行)
28: {
29: j = j + i;
0040120a add ecx,eax 1
0040120c inc eax 1
0040120d cmp eax,10h 1
00401210 jl foo(0x0040120a)+0ah 0 (可并行)
00401212 mov dword ptr [j],ecx 0/1 (取决于上一条指令的分支预
测情况)
30: };
-----------------
16 4.2 (假定分支预测准确度80%)
vc++ 5的最小代码优化生成也有11个字节:
27: for (i = 0; i < 16; i ++)
00401205 xor eax,eax 1
28: {
29: j = j + i;
00401207 add dword ptr [j],eax 1
0040120a inc eax 1
0040120b cmp eax,10h 1
0040121e jl foo(0x00401207)+7 0 (可并行)
30: };
-----------------
11 4
注:
(1) delphi/c++ builder的结果是用turbo debugger直接反汇编的,vc++ 5的结果是从
集成环境的源级调试得到的。
(2) 时钟周期数以pentium处理器为例,实际上,对于没有并行执行单元的cpu(比如
386/486和nx586等)vc++ 5生成的代码速度还要更慢一些。
(3) 分支预测准确度源自intel的"pentium optimization reference"。不过与具体程
序密切相关,一般来说程序中的条件转移指令越密集则分支预测准确度越低。
可以看出,delphi/c++ builder的这段程序有1~1.2个时钟周期的优势。这主要是因为
delphi/c++ builder的编译器比较智能,根本不编译无用的废语句。
(有趣的是,对于这段程序而言,vc++ 5的最大速度优化反而不如最小代码优化生成的
代码运行速度快。)
不要以为1~1.2个时钟周期不算什么,整个程序的快与慢就是这样一个个时钟周期积累
出来的。而且就这几条指令而言相当于快25%~28.6%,是非常可观的数字。
我没有用vc++ 6测试(我从vc++ 5以后不再使用vc了,因为c++ builder 5能完全兼容
vc --- 这种兼容性从c++ builder 3开始就有了,不过一开始并不完善),不知道是否
有改进。有人有兴趣的话请测试一下。
有兴趣的话,可以去jake's code efficiency challenge(http://www.xnet.com/~john
jac)
看一看。那有代码运行性能挑战。目前delphi/c++ builder在6项测试中保持5项领先。
(ps:delphi 2就曾在1996年的pc week的性能测试中击败过vc++ 4.2) |