不借助第三个临时数交换两个整数,无外乎进行所谓的数字魔术,或借助寄存器实现,但除此外还有一种“巧妙的”方法:通过 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 的优化太差了。

解决方案 »

  1.   

    Delphi编译器可以设置是否进行优化的……
      

  2.   

    Delphi的程序编译成exe文件后直接运行exe文件再来评测, 否则与VC的Release相比明显不公。
      

  3.   

    另外, Delphi的工程选择成Console Application, 就和VC工程的运行结果几乎一致了。这段代码,Delphi编译器生成的结果是相当优化的,LZ可以在工程中加个断点,然后进入CPU窗看一下编译出的汇编代码。
      

  4.   

    to 2L:优化全开、调试信息皆无;to 4L:Delphi Compiler 编译是快(不全是其编译器的功劳),但编译出来的程序(优化后)执行效率却很不怎么样...(不说 VCL);to 6L:你可以自己测试下,看结果如何;to 7L:要不俺去你家蹭饭?俺家穷...to 9L:看清楚了,都同样是 Console Application,你可以看下 Delphi 的 CPU 窗口,看是否“相当优化”...
    咱甚至反汇编过 Delphi 和 VC 的(都是优化全开后生成的)控制台程序,唉,结果相当让人沮丧,Delphi 的优化器不是一般的差。
    大家可以自己试试。
      

  5.   

    Delphi能随便把你的代码优化吗
    你写个
    tmp=a;
    a=b;
    b=tmp;
    他也不知道你是干啥啊你觉得ASM快,可以嵌进去嘛
      

  6.   

    晕,这个还要用什么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;