用C ++设计长列表

时间:2011-02-21 10:40:14

标签: c++ user-interface list

我正在尝试设计一个动态列表,其条目可以达到10000.每个列表元素由一个字符串和一个整数组成。我必须从中间件组件请求此列表,填充获取的数据并触发GUI进行显示。 GUI具有高级滚动选项,如拖动,滑动,页面向上/向下,逐行滚动等。因此,我的列表在响应请求方面应该相当快。现在,中间件组件仅支持最多24个列表元素的列表请求。我想在循环中获取整个列表(比如在工作线程中)并维护备份将浪费资源而不是那么有效。但这有一个优点,我可以显示GUI要求我显示的任何元素集。 OR
我可以尝试缓存一组元素。但是,当GUI请求不在缓存中的元素时,我再次怀疑性能是否可接受。任何人都可以给我任何关于如何设计这样的清单的建议/有用的提示?我应该记住哪些因素?我应该如何在最终用户的最佳资源消耗和良好性能之间取得平衡?

5 个答案:

答案 0 :(得分:3)

您的STL收藏品选择:

<强> std::list 在任何点快速插入和删除,但没有随机访问(技术上线性很好)。

<强> std::vector  仅在背面快速插入和删除,但在空间和随机访问中紧凑。

std::deque 在任意一点快速插入和删除。不重新分配或使现有迭代器失效。随机访问。虽然在big-O表示法中都是相同的(两个常量时间),但不存储在连续内存中并且访问速度稍慢于矢量。

如果您需要快速随机访问,那么列表不是您的选择。如果您需要在中间快速插入/删除,那么它就是。棘手的情况,通常通过存储两种类型并根据需要计算“分页”来解决。您现在可以理解,当您向下滚动新加载的文档时,为什么分页这么慢。这不仅仅是一种语言特征,它通常是集合的一般特征。 STL集合仅实现通用收集技术。

答案 1 :(得分:0)

这完全取决于中间件。您必须将结构中的数据放到屏幕上。如果中间件是高效的,那么将数据从那里直接放入GUI将与使用任何std :: - 结构一样高效。 (编辑:如果中间件返回指向它自己的数据的指针,则它很快。因为它一次只能返回24个项目,所以它可能不会那么快。)

如果中间件很慢,并且您有资源,请转到工作线程路径。如果你知道要分配多少元素,我建议使用std::vector(在构造函数中设置大小)。否则,您可能需要std::list

答案 2 :(得分:0)

我认为这个问题并不是特定于C ++的 - 在其他编程环境中也会出现同样的问题。

您的最终解决方案将取决于几个具体细节:

  • 在启动时加载整个列表真的有问题吗?这真的需要太长时间,还是占用稀缺的资源?
  • “获取”操作的延迟和吞吐量是多少?
  • 如果中间件实际上通过某个网络连接检索值:如果与服务器的连接意外地缓慢或丢失会发生什么?
  • 您是否需要考虑其他用户动态更改或添加行的可能性?

如果加载整个列表确实是一个问题,您可能需要一个缓存某些值的解决方案,并在单独的线程中检索新值(尽可能大批量)。即使“获取”很慢,您也希望UI保持响应。您可能希望为仍在检索过程中的行显示“抓取...”之类的内容。

答案 3 :(得分:0)

一个好方法,如果GUI请求不在缓存中的元素,则为尚未加载的项显示一些虚拟值(如“Loading ...”)。然后,您可以设置回调以在加载这些项目后重绘GUI列表。

在需要所有同步的情况下做这样的事情非常棘手,但如果你想让它平滑,有时候这是必要的。

关于如何存储缓存数据 - 我认为应该是这个问题的简单部分。当然你不应该缓存所有 10,000项 - 所以你使用的数据结构不是那么敏感。

答案 4 :(得分:0)

我认为你想要的是一个来自功能世界的方法 - 一个在语法上与列表相同的类,但在语义上是一个知道如何从实际列表中检索相关数据的函数。

基本上,您首先要编写一个空列表类,其中的接口具有您想要执行的所有操作。构造函数应该做一件事:存储引用,句柄,指针或访问中间件数据所需的任何内容。实现所有典型功能,以便它们实际重定向到中间件,并保留尽可能少的实际数据。

我在F#中做了类似的事情,我有一个矩阵(二维字节数组),需要一个表示矩阵单元格的类,我不想制作一个矩阵单元格对象的数组。因此,我实现了矩阵单元类,以便它存储对实际矩阵和两个坐标的引用。访问数据总是转到矩阵中的坐标并获取(或写入)该值。

当你完成后,你可以随时添加一些缓存机制,如果你发现你可以加快速度,正如你提到24项批量操作所暗示的那样。

*顺便说一下,我不是在谈论operator()。术语“函数”在这里以更加语义的方式表示。