【问题标题】:Which k-merge sorting will be more efficient in external sorting哪种k-merge排序在外部排序中会更高效
【发布时间】:2015-12-07 06:07:00
【问题描述】:

我正在解决一个问题,其中我有80GB 需要排序的数据。我只有1GB 主内存来对数据进行排序。显然,我们将在这里应用外部排序方法。但我的问题是哪种 k-merge 排序会更有效?

  • 8 路合并后 10 路合并
  • 5 路合并后 16 路合并

K-merge 排序的复杂度为O(nk^2),其中n 为元素个数。假设我用这种方法计算复杂度:

8 路合并后 10 路合并

8 way merge - O(n*8^2) => O(64n)
10 way merge - O(8n*10^2) => O(800n)

Total time complexity => O(64n) + O(800n)

5路合并后16路合并

5 way merge - O(n*5^2) => O(25n)
16 way merge - O(5n*16^2) => O(1280n)

Total time complexity => O(25n) + O(1280n)

查看时间复杂度5 way merge followed by 16 way merge 似乎需要更多时间。你觉得我的流程对吗?我对此不是很有信心。

更新:@rcgldr 既然您说更大的块大小将花费更少的时间来读取/写入,那么您如何看待这个公式:

Time to read/write  1 block = Average Seek time + 
Average rotational latency + blocksize/Maximum Transfer Rate

根据这个公式,如果块大小很小,那么整体读/写时间也会更短。你觉得这里有什么问题吗?或者我们需要将块的总数与此相乘才能准确了解所需的总时间。

【问题讨论】:

    标签: algorithm sorting merge computer-science external-sorting


    【解决方案1】:

    这是一种外部排序,因此通常的时间复杂度不适用,至少在现实世界中不适用。

    为了澄清第一个语句,内存(不是外部)中的 k 路合并(不是合并排序)合并了 k 个大小为 n 的数组,因此移动了 k n 个数据,在一个简单的版本中,k-1 个比较是每次移动,所以 (k n) (k-1) = n k^2 - n k => O(n k^2)。如果使用堆/优先级队列/...来跟踪当前最小元素集,则比较次数减少到 log2(k),因此 O(n k log2(k))。

    内存中 n 个元素的 k 路合并排序需要 ⌈logk(n)⌉ == ceil(logk(n)) 次,每次移动 n 个元素,因此 n ⌈logk(n)⌉。使用堆/优先队列/...实现k个元素的比较需要⌊log2(k)⌋ == floor(log2(k)),所以 (n ⌈logk(n)⌉ ) (⌊log2(k)⌋ )。如果n是k的幂,k是2的幂,那么复杂度就是n logk(n) log2(k) = n log2(n)。 k 与复杂性无关,但实际运行时间可能更好或更差,k > 2 意味着比较次数更多,但移动次数更少,因此问题在于比较开销与运行开销,例如对指向对象的指针数组进行排序。

    回到外部排序,假设进程是I/O绑定的,那么复杂度与I/O有关,而不是cpu操作。

    这两种方法都需要 3 次读取/写入 80GB 数据。第一遍创建 80 个 1GB 集群实例。下一遍一次合并 5 或 8 个簇,最后一遍一次合并 16 或 10 个簇。主要问题是一次读取或写入大量数据以减少随机访问开销。 16 路合并会将 1GB 的内存分成比 10 路合并更小的块,这可能会对随机访问开销产生轻微影响,因此 8 / 10 方法可能会更快一些。如果使用固态驱动器进行外部排序,那么随机访问/块大小就不是问题了。

    另一个问题是 10 路或 16 路合并在内存中运行的速度是否足够快,以至于合并过程是 I/O 绑定的。

    【讨论】:

    • 如果我只使用单一的8 方式合并排序进行外部排序与两阶段8/10 合并排序进行外部排序。你能告诉我它对运行时间有什么影响吗?
    • 您能稍微描述一下为什么2 phase merge sort 更高效吗?我正在维基百科上阅读它,但无法理解。
    • @python - 5/16 或 8/10 合并排序将是 3 阶段合并排序。 80 路归并排序将是 2 个阶段,但如前所述,比较开销和缓冲区大小足够小,以至于 8/10 可能更快。
    • 你能看到我的编辑吗,我已经更新了那里的问题。这将是最后一个问题? :) 你能回答一下吗!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 2022-01-06
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    相关资源
    最近更新 更多