最佳算法是什么,用于合并一个大的排序数组和一个小的未排序数组?
我将从我的特定用例中给出示例,但不要受限于它们:我主要是试图让您了解这个问题。
8 MB排序数组与92 kB未排序数组(缓存内排序)
2.5 GB排序数组与3.9 MB未排序数组(内存排序)
34 GB排序数组与21 MB未排序数组(out-of-memory排序)
最佳算法是什么,用于合并一个大的排序数组和一个小的未排序数组?
我将从我的特定用例中给出示例,但不要受限于它们:我主要是试图让您了解这个问题。
8 MB排序数组与92 kB未排序数组(缓存内排序)
2.5 GB排序数组与3.9 MB未排序数组(内存排序)
34 GB排序数组与21 MB未排序数组(out-of-memory排序)
O(n (1 + log(m) / c) + m (1 + log(c)))
,其中m
是大数组的长度,n
是小数组的长度,c
是块大小(为了清晰起见,超级块在此被忽略,但它们只像常数因子c
一样改变复杂度)。
替代方法/优化:如果您的比较运算符简单且可以使用SIMD指令进行向量化,则可以优化传统的合并算法。传统方法由于分支(在一般情况下很难预测)以及不能轻松/高效地进行向量化而相当缓慢。然而,由于大数组比小数组大得多,传统算法将从大数组中挑选许多连续值,这些连续值在小数组的值之间。这意味着您可以选择大数组的SIMD块,并将其与小数组中的一个值进行比较。如果所有SIMD项都小于从小数组中选择的项,则可以非常高效地一次写入整个SIMD块。否则,您需要写入SIMD块的一部分,然后写入小数组的项并切换到下一个项。这最后一个操作显然不太有效,但应该很少发生,因为小数组比大数组小得多。请注意,小数组仍然需要先进行排序。