TListbox排序 - 高点和低点

时间:2009-09-10 15:07:30

标签: delphi sorting shuffle

好的,我有一个TListBox,有时可能会被要求显示43,000行!

我知道,这几乎没有任何意义,但确实如此。

现在这是当前的问题:

使用内置的Sort方法及其Compare回调函数,几乎可以持续几分钟。

因此,我将列表框中的字符串从ShortStrintgs的普通旧动态数组中提取出来,对其执行QuickSort(),大约需要三秒钟。我想是啊!

做一些思考,我看到QuickSort正在移动所有这些字符串,这是没有必要的,所以我把代码只是移动指针或索引到字符串,瞧,排序很多更快,羚牛在一秒钟内排序43,000项。大赢,是吗?

但是,现在,如果我执行LB.Items.Add()或LB.Items.Assign将已排序的字符串移动到列表框中,则需要30秒!即使发生了BEgin / EndUpdate。如果我浏览代码,我会看到很多内容正在继续使用delete()Insert()INsertObject()和Windows消息没有任何理由。

片刻虽然揭示了我拥有LB.TStrings中的所有字符串,但我只需要将它们拖到我的QuickSorted()数组周围。这应该是微不足道的,只是移动一些指针。

但我没有看到任何可见的方法来设置原始TStringList指针。不,Exchange()真的很慢。

我有什么想法可以获得TString字符串指针?这应该是微不足道的,但我没有看到它。

谢谢,

乔治

5 个答案:

答案 0 :(得分:5)

所有这些消息实际上都是飞来飞去的原因很充分。没有魔法“显示列表中的任何内容”功能。它必须获取列表的内容,从中构建一个树,一次一个项目,并显示该树的任何部分恰好落在可视控件的ClientRect中。你的外部字符串列表技术听起来像是你将要获得的最快的东西。

如果您想获得更好的性能,请尝试查看更快的列表框。我听说Virtual TreeView在添加大批新产品时速度非常快,但由于我没有使用它并自行测试,我无法推荐它。但您可能需要查看一下,看看它是否比您现有的设置更适合您的需求。

答案 1 :(得分:4)

您是否尝试过将TListBox.Style设置为lbVirtual?然后列表框会要求您提供OnData()事件中的数据

请参阅 http://www.delphi3000.com/articles/article_3761.asp?SK=

答案 2 :(得分:1)

您可以使用的其他一种方法(我已经成功使用它)来帮助保持速度快,就是停止应用程序重新绘制控件,将列表复制到第二个TStringList,对TStringList进行排序,然后复制回来。停止重绘的关键是这样的命令:

SendMessage(Application.Handle, WM_SETREDRAW, 0, 0);

第一个0告诉应用程序停止绘制到窗口,因此所有这些消息立即被删除,应用程序可以更快地移动。准备好重绘屏幕时,只需将第一个0换成1然后再调用

RedrawWindow(Application.Handle, nil, 0, [Options])

迫使立即重绘一切。

答案 3 :(得分:1)

试试Virtual Treeview。我知道它不是一个列表框,它比tlistbox有点复杂,但它可以像TListBox(或tlistview / ttreeview)一样,它比标准tlistbox / tlistview / ttreeview更快。(它可以在125ms内添加1000000项)

答案 4 :(得分:0)

要在重新排序字符串时停用更新列表框控件,请使用BeginUpdate / EndUpdate

ListBox.Items.BeginUpdate;
try
  // your sorting here...
finally
  ListBox.Items.EndUpdate;
end;

编辑:您还可以尝试虚拟样式(Style = lbVirtual,设置Count属性并处理OnData事件。)