循环1:
for i := 1 to 64 do
begin
TListViewAddColumn(ListView, GetClStr(Colm[i]), taRightJustify, Column[i]);
end;
循环2:
repeat
TListViewAddColumn(ListView, GetClStr(Colm[i]), taRightJustify, Column[i]);
pTmpNode := pTmpNode.next;
until pTmpNode = pHeadNode
循环1 以及循环2都执行了64次,循环体中的代码完全一致。不同的地方在于循环2,是对链表节点的访问。就这点差异,造成的结果是 循环2的运行时间明显多于循环1。我测了很多次,循环1的执行时间分布在200 - 300毫秒之间,而循环2的执行时间分布在450 - 600毫秒之间。各位同仁朋友是否有遇到这种情况的,麻烦解答一下,多谢了。
注:为了不造成不必要的误解,我稍微解释一下,循环2中的变量 i其实就是链表每个节点的数据域的值 (pTmpNode.data),即 i = pTmpNode.data, 因为写成pTmpNode.data会使代码很长。
链表是利用有限的内存资源的好方式,同时自然会降低速度;普通方式占用内存大,系统运行不考虑每次的开辟空间与释放,就会快。
这个速度下降的有点太快吧,就循环64次而已。
你是怎么算的耗时?是单独这段代码么?200ms对于计算机来说,是很多时间了,对于现代处理器来说,相当于执行了十亿级别的指令才耗时几百毫秒,你只循环了64次
因为你访问了控件,所以感觉是你的系统里有些Hook之类的东西在拖累你的程序的性能。一些杂七杂八的软件是否关闭。
你是否在计算时间的时候包括了控件载入之前或者之后的时间。
另外pTmpNode := pTmpNode.next;这个next是怎么实现的
理论上来说 3种循环方式只是应用场景不同, for循环的效率要高于while和repeat, 因为for是已知次数循环(循环开始后, 次数不会被count变量影响), 而while/repeat是未知
这样就导致了每次循环while/repeat要花费额外的消耗去进行条件判断(根据条件不同, 性能消耗也不一样)
但是你的代码仅仅64次循环性能差能到300毫秒, repeat的条件也仅仅是个比较, 所以猜测应该是pTmpNode.next导致了额外的消耗
所以, 先使用相同的代码测试2种循环的执行效率, 再判断性能差再什么地方(如果有能力, 看看CPU指令窗口分析)
for i := 1 to 64 do
begin
TListViewAddColumn(ListView, GetClStr(Colm[i]), taRightJustify, Column[i]);
end;
i := 1;
repeat
TListViewAddColumn(ListView, GetClStr(Colm[i]), taRightJustify, Column[i]);
inc(i);
until i >= 64