当前位置: 首页 > 面试题库 >

在显示进度的同时对大型馆藏进行排序

赏逸春
2023-03-14
问题内容

更新进度条时对集合排序的最佳方法是什么?目前,我有这样的代码

for (int i = 0; i < items.size(); i++)
{
    progressBar.setValue(i);

    // Uses Collections.binarySearch:
    CollectionUtils.insertInOrder(sortedItems, item.get(i));
}

这显示进度,但是进度条随着项目数量的sortedItems增加而减慢。有谁有更好的方法?理想情况下,我想使用类似于的接口,Collections.sort()以便尝试不同的排序算法。

任何帮助将是巨大的!

作为背景,这段代码正在从Lucene撤回许多文档(1到1000万个),并在它们之上运行自定义比较器。通过将数据写回到磁盘上对它们进行排序将太慢而无法实用。大部分成本是从磁盘上读取项目,然后在项目上运行比较器。我的电脑有大量的内存,因此没有与交换到磁盘等有关的问题。

最后,我选择了Stephen的解决方案,因为它非常干净,使我可以轻松添加多线程排序算法。


问题答案:

您在这里要小心。您已选择使用一种算法来增量构建排序的数据结构,以便(我接受)您可以显示进度条。但是,这样做时,您选择的排序方法 可能
比最佳排序慢得多。(两种类型都可以,O(NlogN)但是性能要比big-O行为更多…)

如果您担心这可能是个问题,请比较使用TreeMap和对典型集合进行排序的时间Collections.sort。后者的工作方式是将输入集合复制到数组中,对数组进行排序,然后再将其复制回。(它的工作原理最好的,如果在输入集合是一个ArrayList,如果你不需要结果作为可变集合就可以避免使用最终拷贝过来的Collection.toArrayArrays.sortArrays.asList代替。)

一种替代方法是使用Comparator对象,该对象跟踪被调用的次数,并使用该对象跟踪排序的进度。您可以利用以下事实:比较器通常会被粗略调用N*log(N),尽管您可能需要根据实际使用的算法1对其进行校准。

顺便说一下,与对插入次数进行计数相比,对比较器的调用进行计数可以更好地指示进度。当您接近完成排序时,您将不会看到进度出现放缓的趋势。

(您将拥有不同的线程来读取和写入计数器,因此您需要考虑同步。声明计数器volatile可以正常工作,但会增加内存流量。如果您对进度条感到满意,也可以忽略该问题有时会显示过时的值…具体取决于您的平台等)

1-这有问题。在某些算法中,比较次数可能会根据要排序的数据的初始顺序而急剧变化。对于这种算法,没有办法校准将在“非平均”情况下工作的计数器。



 类似资料:
  • 问题内容: 更新进度条时对集合排序的最佳方法是什么?目前,我有这样的代码: 这显示进度,但是进度条随着项目数量的增加而减慢。有谁有更好的方法?理想情况下,我想使用类似于的接口,以便尝试不同的排序算法。 任何帮助将是巨大的! 作为背景,这段代码正在从Lucene撤回许多文档(1到1000万个),并在它们之上运行自定义比较器。通过将数据写回到磁盘上对它们进行排序将太慢而无法实用。大部分成本是从磁盘上读

  • 介绍 考虑以下示例: 使用运行以升序打印数组中的排序数字: 问题 考虑两个(一般来说,对于< code>N)对应数组< code>a和< code>b的扩展情况 以及“同时”排序所有数组的问题..为了实现这一点,我需要对数组< code>a进行排序,还需要获取排序的索引。对于这个简单的例子,指数由下式给出 有了这些索引,我就可以根据数组 的排序结果打印出排序后的 数组。例如: 将打印排序的数组。。

  • 我想按值长度对Map进行排序。例如,我有这样的代码: 结果是: 所以我想做的是按值长度对这个Map进行排序,所以它返回:

  • 我有一个名为map的HashMap,它将字符存储为键,将整数存储为值,然后使用以下代码将其存储到名为entries的ArrayList中: 现在我正在尝试根据整数值而不是键对这些条目进行排序。我试图使用一个lambda表达式来实现比较器接口,但它不起作用。这是我的代码: 以下是我得到的错误: 这一行有多个标记 > 语法错误,插入“)”以完成表达式 类型集合中的方法sort(列表,比较器)不适用于参

  • 问题内容: 我有一个PHP脚本,可能至少需要10秒钟才能运行。我想为用户显示进度。 在执行类中,我有一个随进度(在1-100中)更新的属性和一个方法(其目的应该很明显)。 问题是,如何更新前端的元素以供用户查看? 我认为AJAX是解决方案,但我只是无法解决。我无法到达同一对象实例。 问题答案: 如果您的任务是上载庞大的数据集或在服务器上处理它,则在将进度更新到服务器时,您应考虑采用某种作业架构,在