创建一个快速case语句(程序集)



我有一个项目大量使用case语句,其中包含许多过程。我知道你可以将case语句放在两个撕裂的排列中,以10为块,第二个case语句分隔各个过程。但如果我能成功,我有一个更好的主意。我想把它称为组装案例

Prolist: array [1..500] of Pointer =
          (@Procedure1, @Procedure2, @Procedure3, @Procedure4, @Procedure5);

Procedure ASMCase(Prolist: array of Pointer; No: Word; Var InRange: Boolean);
var Count : DWord;
    PTR: Pointer;
    Pro : Procedure;
begin
  Count := No * 4;
  InRange := boolean(Count <= SizeOf(Prolist));
  If not InRange then Exit;
  PTR := Pointer(DWord(@Prolist[1]) + Count);
  If PTR <> nil then Pro := @PTR else Exit;
  Pro;  /run procedure
end;​

重点是我正在创建一个直接跳转到过程的过程。在我的情况下,过程可以有一个相同的头,并且可以访问任何奇怪信息的全局数据。我认为在汇编中编写它会更快,但我不确定的是运行程序。请不要问我为什么要这样做,因为我有500个过程,对案例陈述有很多调用,时间对于快速处理器至关重要。

按值传递该数组的成本很高。按常量传递。

我看不出InRange标志和测试的意义。不要传递超出范围的索引。如果你必须测试,那就做对。不要使用测量字节大小的SizeOf。如果必须的话,可以使用highLength。我对此表示怀疑。

指针分配测试(PTR <> nil)是伪造的。该条件的求值结果始终为true。数组索引非常奇怪。[]出了什么问题?

最重要的是,您的数组是基于1的(通常是一个糟糕的选择),但开放数组总是基于0的。这可能会绊倒你。

简而言之,我会扔掉所有的代码。这既错误又不必要。我会这样写:

ProList[No]();

为了进行编译,需要将数组定义为过程类型的数组,而不是Pointer的数组。增加一些类型的安全性将是一个不错的举措。

很难看出asm在这里有多大的不同。编译器将发出最佳代码。

如果您关心越界访问,请在调试模式下启用范围检查。如果性能至关重要,请禁用它以进行发布。

请记住,随着复杂性的增加,全局数据结构往往不会很好地扩展。大多数有经验的程序员都会尽量避免全局状态。你确定全球状态对你来说是正确的选择吗?

如果您确实需要改进性能,首先要确定改进的机会。读取数组和调用函数不太可能。看看你调用的过程。瓶颈肯定存在。

最后一点。试着忘记你曾经学习过将@与函数指针一起使用。这样做会产生一个类型为Pointer的非类型化指针,该指针可以分配给任何指针类型。因此,您完全放弃了类型检查。您的过程可能完全有错误的签名,编译器无法告诉您。使用类型安全的过程类型声明过程数组。

最新更新