好的,我有一个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字符串指针?这应该是微不足道的,但我没有看到它。
谢谢,
乔治
答案 0 :(得分:5)
所有这些消息实际上都是飞来飞去的原因很充分。没有魔法“显示列表中的任何内容”功能。它必须获取列表的内容,从中构建一个树,一次一个项目,并显示该树的任何部分恰好落在可视控件的ClientRect中。你的外部字符串列表技术听起来像是你将要获得的最快的东西。
如果您想获得更好的性能,请尝试查看更快的列表框。我听说Virtual TreeView在添加大批新产品时速度非常快,但由于我没有使用它并自行测试,我无法推荐它。但您可能需要查看一下,看看它是否比您现有的设置更适合您的需求。
答案 1 :(得分:4)
您是否尝试过将TListBox.Style设置为lbVirtual?然后列表框会要求您提供OnData()事件中的数据
答案 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
事件。)