delphi - 为什么这种 RTTI 优化会使速度变慢?

标签 delphi optimization rtti

我有一个在循环中重复调用的操作。使用 TRttiField:

if (field.name = '') or (field.Name[1] <> 'F') then
  continue;

分析显示,因此我在 UStrAsg 和 UStrClr 上花费了大量时间。 Field.Name 必须对 TRttiInstanceFieldEx.GetName 进行虚拟调用,后者必须对底层 RTTI 结构的名称执行 UTF8 到字符串的转换。每个循环迭代都会发生两次。

我试图通过绕过字符串转换来消除所有这些:

handle := PFieldExEntry(field.Handle);
if (handle.name = '') or (handle.Name[1] <> 'F') then
      continue;

我预计速度会因此提高 5% 左右。相反,循环的执行时间要长几秒,大约慢 20-25%!我检查了生成的 ASM,以确保它没有做任何奇怪的事情,比如将字符串从 RTTI 结构复制到本地堆栈,但事实并非如此。我看不出有什么理由让它变慢。有人知道这里会发生什么吗?

最佳答案

新代码读取的字段被声明为 ShortString。从 Delphi 5 开始,编译器在生成大多数字符串操作的代码之前将 ShortString 转换为长字符串。 (至少,非 Unicode Delphi 就是这样。也许 Unicode Delphi 恢复了一些与 ShortString 相关的优化。)

虽然 TRttiField 包装器可能会利用它正在用每个字符已经占用一个字节的数据填充 UTF-8 字符串的知识,但我预计您的新循环使用的 ShortString-to-string 代码可能会使用更通用的转换例程,并且您要为通用性付出代价。

您可以完全尝试上述字符串转换操作。相反,获取指向第一个字节的指针:

handle := PFieldExEntry(field.Handle);
NameP := PAnsiChar(@handle.name);
if (NameP[0] = #0) or (NameP[1] <> 'F') then
  continue;

请注意,虽然它被声明为 ShortString,但它实际上并不是一个。它实际上并不占用256字节。相反,它占用保存其长度字节及其字符所需的最小内存量。

关于delphi - 为什么这种 RTTI 优化会使速度变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5188310/

相关文章:

delphi - 如何在 "uses"子句中创建子库?

德尔福XE2 : How to pass a field with null value?

c++ - 对齐数据成员和成员函数以提高性能

C++ 类引用

Delphi (Pascal) 检查每个字段是否赋值

c++ - 将 std::forward 与 typeid 运算符一起使用是否有意义?

delphi - 消息队列中的访问被拒绝

delphi - 使 TChromium 渲染抗锯齿

c++ - 什么是用于矩阵运算的好 C++ 库

facebook-graph-api - 查询优化和 API 限制