delphi - Delphi 真的比处理静态类更好地处理动态类吗?

标签 delphi optimization dynamic static delphi-2009

我不止一次被告知 Delphi 处理动态类比静态类更好。因此使用以下内容:

type Tsomeclass=class(TObject)
  private procedure proc1;
  public 
    someint:integer;
    procedure proc2;
end;

var someclass:TSomeclass;

implementation

...

initialization
  someclass:=TSomeclass.Create;
finalization
  someclass.Free;

而不是

type Tsomeclass=class
  private class procedure proc1;
  public 
    class var someint:integer;
    class procedure proc2;
end;

我正在处理的项目中 90% 的类只有一个实例并且只需要一个实例。我真的必须使用第一种方法来使用这些类吗?它是否经过更好的优化,由 Delphi 处理?

对不起,我没有论据支持这个假设,但我需要专家的意见。

提前致谢!

最佳答案

如果你创建一个只包含类变量和类方法的类,那么你可以在没有实例化的情况下使用它。 IE。在您的第二个示例中,您可以使用 Tsomeclass.proc2(但不能使用 Tsomeclass.someint,因为这个变量没有像 Uwe 指出的那样标有“class”前缀)。

对于(无法测量的小)速度差异,您还可以将类方法标记为“静态”。

type
  TSomeclass = class
    class procedure proc2; static;
  end;

在我看来,这里没有“处理得更好”的比较。 Delphi 允许您在类中放置“普通”和“类”成员。前者你只能在实例化对象上使用,后者你可以在任何地方使用。但这只是 Delphi 中 OO 支持的两个部分。

编辑:回答关于速度的问题......

让我们编写一个小测试程序:

program Project61;

{$APPTYPE CONSOLE}

type
  TTestClass = class
    procedure A(a: integer);
    class procedure B(b: integer);
    class procedure C(c: integer); static;
  end;

procedure TTestClass.A(a: integer); begin end;
class procedure TTestClass.B(b: integer); begin end;
class procedure TTestClass.C(c: integer); begin end;

var
  tc: TTestClass;

begin
  tc := TTestClass.Create;
  tc.A(42);
  tc.B(42);
  tc.C(42);
  tc.Free;
  //TTestClass.A(42); // not possible
  TTestClass.B(42);
  TTestClass.C(42);
end.

启用优化的 Delphi 2010 将 .A/.B/.C 调用编译成

Project61.dpr.30: tc := TTestClass.Create;
004060C5 B201             mov dl,$01
004060C7 A154594000       mov eax,[$00405954]
004060CC E847DAFFFF       call TObject.Create
004060D1 8BD8             mov ebx,eax
Project61.dpr.31: tc.A(42);
004060D3 BA2A000000       mov edx,$0000002a
004060D8 8BC3             mov eax,ebx
004060DA E899F9FFFF       call TTestClass.A
Project61.dpr.32: tc.B(42);
004060DF BA2A000000       mov edx,$0000002a
004060E4 8B03             mov eax,[ebx]
004060E6 E891F9FFFF       call TTestClass.B
Project61.dpr.33: tc.C(42);
004060EB B82A000000       mov eax,$0000002a
004060F0 E88BF9FFFF       call TTestClass.C
Project61.dpr.34: tc.Free;
004060F5 8BC3             mov eax,ebx
004060F7 E84CDAFFFF       call TObject.Free
Project61.dpr.36: TTestClass.B(42);
004060FC BA2A000000       mov edx,$0000002a
00406101 A154594000       mov eax,[$00405954]
00406106 E871F9FFFF       call TTestClass.B
Project61.dpr.37: TTestClass.C(42);
0040610B B82A000000       mov eax,$0000002a
00406110 E86BF9FFFF       call TTestClass.C

首先创建对象并将其地址存储到 ebx 寄存器中。

为了调用 tc.A,编译器在 edx 中准备参数(42 或 $2A),在 eax 中准备“tc”实例的地址并调用 TTestClass.A。

几乎相同的情况发生在 tc.B 的情况下,除了 ebx 被取消引用。

在 .A 和 .B 的情况下,eax 包含“Self”的值(相当于 C++ 的“this”)。调用 tc.A 时,eax 包含“tc”实例的地址。调用 tc.B 时,eax 包含其他内容(我猜它指向 TTestClass 的类型信息,但我不太确定)。

当代码调用 tc.C 时,只准备 eax,因为“静态”方法不能引用“Self”。

类似的情况发生在 TTestClass.B/.C 的情况下,除了当 ??TTestClass 类型信息的地址?被储存了。无论如何,当 B 通过实例 (tc.B) 或通过类 (TTestClass.B) 调用时,eax 包含相同的值。

所以你可以看到静态调用需要少一个'mov'。这就是我所指的不可估量的加速。

关于delphi - Delphi 真的比处理静态类更好地处理动态类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2612901/

相关文章:

ios - Delphi XE5下如何查找分辨率

c - 将当前/选定的用户添加到组

Delphi - TWebBrowser 中的证书错误,IE9 中没有错误

c++ - std::vector<T>::iterator 可以只是 T* 吗?

c++ - 在这种特殊情况下,您会推荐使用程序集来访问参数吗?

jquery - 使用 jQuery 将样式表附加到 iframe

javascript - 获取动态创建的元素 jQuery 的 id

delphi - 缩放比例 + 轨迹栏

performance - Windows Phone 7模拟器/性能问题

java - 在java代码中使用相对布局