5

谁能告诉我将容器中的对象分配给局部变量是否有任何性能优势,如果它在紧密循环中使用很多。

我有一个大的 for 循环,并且在循环内经常访问来自容器的对象。IE

for i := 0 to 100000 do
begin
  my_list[i].something := something;
  my_list[i].something_else := something;
  my_list[i].something_else := something;
  my_list[i].something_else := something;
  my_list[i].something_else := something;
end;

我会通过分配看到性能改进吗

local_ref := my_list[i];

在每次迭代开始时?我正在使用通用容器(TList<<>MyObject<>>)。

4

2 回答 2

9

进行您建议的更改肯定会导致更快的代码。访问局部变量总是比访问属性 getter on 更快TList<T>。首先,这些 getter 对索引执行有效性检查。但是,即使对于具有最简单 getter 的类,也很难在性能上击败缓存的本地。

现在,从这里不可能说这对你的情况是否重要。如果您在循环内执行任何远程非平凡的操作,那么项目 getter 的运行时间将是无关紧要的。循环可能会运行大量迭代这一事实并不是关键因素。最重要的是您在每次迭代中花费了多少时间。如果调用项目 getter 需要 1 个时间单位,而对每个项目执行任何操作需要 1000 个时间单位,那么 getter 性能不是问题。

最终,回答这个问题的最终方法是确定备选方案的时间。仅基于测量进行优化。

将项目复制到局部变量中有一个更好的理由:表达的清晰性。您当前的代码严重违反了DRY 原则

最后,如果它使用 for in 循环,这段代码会读起来最好:

for Item in List do
  ....

现在,for in 循环可能比传统循环慢,但你应该权衡它的清晰度和可维护性。优化通常使代码更难维护并且更容易出错。结论:只优化瓶颈。

于 2012-11-29T19:07:55.417 回答
4

这一切都取决于如何my_list[i]检索。如果它导致一堆函数调用,它可能会产生影响(更不用说任何副作用)。

像往常一样,您应该在进行任何类型的性能重构之前进行测量。过早的优化......

with作为记录,它是原始 Pascal 设计中“好的”用途之一:

with my_list[i] do
begin
  something := something_else;
  [...]
end;
于 2012-11-29T19:00:49.797 回答