Algorithm 在外部排序中,哪个k-merge排序更有效

Algorithm 在外部排序中,哪个k-merge排序更有效,algorithm,sorting,merge,computer-science,external-sorting,Algorithm,Sorting,Merge,Computer Science,External Sorting,我正在处理一个问题,其中有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 ti

我正在处理一个问题,其中有
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 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路合并后16路合并

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 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路合并和16路合并似乎需要更多的时间。你认为我的流程正确吗?我对此不太自信

更新:@rcgldr因为您说较大的块大小将减少读/写时间,所以您如何看待此公式:

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

根据此公式,如果块大小较小,则总体读/写时间也将较少。你认为这里有什么不对劲吗?或者我们需要将块的总数与此相乘,以获得所需总时间的准确图像。

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

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

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

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

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


另一个问题是,10路或16路合并是否在内存中运行得足够快,以致合并进程受I/O限制。

如果我只使用单路
8路
合并排序进行外部排序,与两阶段
8/10
合并排序进行外部排序。您能告诉我它在运行时间上有什么区别吗?您能稍微描述一下吗为什么
2阶段合并排序
更有效?我在维基百科上读到过,但不理解。@python-5/16或8/10合并排序将是3阶段合并排序。80路合并排序将是2阶段,但如前所述,比较开销和缓冲区大小,使8/10可能更快。你能看到我的编辑吗,我有更新这将是最后一个问题?:)你能回答这个问题吗!