当数据不适合内存时,网上有很多关于在Unix上对大文件进行排序的讨论。通常使用mergesort和variants。
Hoewever,如果假设有足够的内存来容纳整个数据,那么最有效/最快的排序方式是什么? csv文件大约为50 GB(> 10亿行),并且有足够的内存(数据大小的5倍)来保存整个数据。
我可以使用Unix排序,但仍然需要> 1小时我可以使用任何必要的语言,但我主要想要的是速度。我知道我们可以将数据加载到一个柱状类型的数据库表和排序中,但这是一次性的努力,所以寻找更灵活的东西......
提前致谢。
答案 0 :(得分:4)
对大量数据使用并行排序算法。
有用的主题: Which parallel sorting algorithm has the best average case performance?
答案 1 :(得分:1)
QuickSort怎么样?你试过了吗? std :: sort通常由quicksort实现(更精确的是introsort,如果quicksort性能不好,会切换到heapsort),所以你可以尝试使用它。快速排序通常是最快的选择(尽管最坏情况的复杂性是O(n ^ 2),但在通常情况下它会击败所有其他排序算法)。
快速排序的空间复杂性不应该太差,它需要log2(N)堆栈空间,大约30个堆栈帧,10亿个项目。
然而,它是不稳定的排序算法(不保留“相等”项目的顺序),所以这取决于你是否正常。
顺便说一下。 Unix排序似乎是通过合并排序实现的,这通常不是RAM内排序的最快选择。
答案 2 :(得分:0)
我知道这已经过时了,但我想我会同意我刚刚发现的内容,希望它可以在未来帮助其他人。
您可能已经知道 GNU 排序非常快。将它与许多 CPU 内核和大量 RAM 结合起来,当您将一些特殊标志传递给 GNU 的排序并使其非常快时。
* 密切注意 'buffer-size' 标志。缓冲区大小是这种加速的主要原因。我之前使用过并行标志,但它本身并没有那么快。
sort --parallel=32 --buffer-size=40G -u -t, -k2 -o $file.csv $file
我使用了 for 循环来处理文件夹中的所有文件,并通过第二个键对巨大的 csv 文件进行排序,使用逗号分隔符,只保留唯一值,结果如下:
for file in $(ls -p | grep -v -E "[0-4/]");
do
time sort --parallel=32 --buffer-size=40G -u -t, -k2 -o $file.sorted.csv $file;
done
real 0m36.041s
user 1m53.291s
sys 0m32.007s
real 0m52.449s
user 1m52.812s
sys 0m38.202s
real 0m50.133s
user 1m41.124s
sys 0m38.595s
real 0m41.948s
user 1m41.080s
sys 0m35.949s
real 0m47.387s
user 1m39.998s
sys 0m34.076s
输入文件为 5.5 GB,每个文件约 75,000,000 百万行。我在进行排序时看到的最大内存使用量略低于 20 GB。因此,如果它按比例缩放,那么 50 GB 的文件应占用的空间应该比 200 GB 少一点。在 9 分钟内整理了 27.55 GB 的数据!