我依靠VirtualTreeView来显示数千个偶尔会发生变化的项目,当这种情况发生时,树会被清理并重新填充。
排序是自动完成的(toAutoSort
标志设置)但这会产生一种不必要的影响,即递归地初始化所有节点,这是一个非常昂贵的操作,你可以想象。
那么,当.Sort
关闭时,我何时应该调用toAutoSort
方法? (DoInitChildren看起来似乎有道理,但我得到了奇怪的结果,比如偶尔反复的结果,所以我认为对儿童进行排序并不是一件好事。)
答案 0 :(得分:4)
此类场景中的一般规则是在添加所有新项目后进行排序。这样你只需要排序(并初始化)一次。
答案 1 :(得分:1)
除非整个树每次都完全不同,否则你可以通过不清除树来获得更好的性能,但是通过单独构建一个新的项目列表(只是标识项目),对列表进行排序,然后将两个树都放在order ...通用算法看起来像这样(左侧列表是“新列表”,右侧列表是“现有列表”):
LeftCur := 0;
RightCur := 0;
while (LeftCur < TotalLeft) and (RightCur < TotalRight) then
begin
if LeftList[LeftCur] = RightList[RightCur] then
begin
// matches, so just advance
Inc(LeftCur);
Inc(RightCur);
end
else if LeftList[LeftCur] < RightList[RightCur] then
begin
// insert happens BEFORE RightCur
InsertLeftItemToRight;
Inc(RightCur);
Inc(TotalRight);
end
else if LeftList[LeftCur] > RightList[RightCur] then
begin
DeleteRightItem;
Dec(TotalRight);
end;
end;
While RightCur < TotalRight do
begin
DeleteRightItem;
Dec(TotalRight);
end;
While LeftCur < TotalLeft do
AppendLeftItemToRight;
这样列表仍然排序,您只需在InsertLeftItemToRight步骤中完成加载项目。在树中,无论何时匹配,都会为子项运行类似的例程。这个概念的重点在于现有列表中的项目不会发生太大变化或者完全加载可能很昂贵。