大文件排序思想: 首先将大文件分割为每个都可以放入内存的临时小文件, 对小文件在内存中进行排序并保存成已排序的小文件, 然后利用多路归并算法将已排序的小文件合并为一个大文件, 这个大文件是已排好序的了.
目前胜者树的使用有问题, 当将胜者放到最终结果后, 它所在的归并段的后继放到胜者树后, 胜者树又从新构造, 效率反而降低了, 需要重新考虑设计.
经过修改, 实现了对胜者树的有效利用: 每次归并数组取出最小值后, 如果当前归并段还有后继元素, 则将其放入归并数组, 替代原来最后的胜者, 并调整胜者树, 否则才会重新构造胜者树, 提高了效率.
下面是一些测试数据: (小文件排序采用的是选择排序, 效率不高)
1. 对1000000行, 每行5个字母的文本文件(约6.67M)按字母顺序排序, 分割的临时小文件每个为10000行, 总共100个小文件, 则
文件分割时间: 283s
分割后所有小文件排序时间: 111641s
排序后小文件归并时间: 540s
2. 对1000000行, 每行5个字母的文本文件(约6.67M)按字母顺序排序, 分割的临时小文件每行为1000行, 总共1000个小文件, 则
文件分割时间: 524s
分割后所有小文件排序时间: 10344s
排序后小文件归并时间: 963s
3. 对1000000行, 每行5个字母的文本文件(约6.67M)按字母顺序排序, 分割的临时小文件每行为100行, 总共10000个小文件, 则
文件分割时间: 3580s
分割后所有小文件排序时间: 15210s
排序后小文件归并时间: 归并失败, 归并路数过多, 导致创建大量BufferedReader, 出现OutOfMemoryError.
4. 对10000000行, 每行5个字母的文本文件(约66.7M)按字母顺序排序, 分割的临时小文件每行为10000行, 总共1000个小文件, 则
文件分割时间: 2765s
分割后所有小文件排序时间: 1101860s
排序后小文件归并时间: 7768s
从上面的实验中可以看到, 整个程序花去的时间主要在小文件的排序上. 小文件越大, 排序越慢, 而减小小文件大小, 会使小文件个数增大, 导致归并路数增大, 需要对归并路数做限制.