假设我们需要对5 000 000个数字进行排序。假设,这些数字存储在一个文件中。解决此问题的最有效算法是什么?并行排序算法......
怎么做?也许有用的链接)
好的..我读过有关并行合并的内容......但对我来说并不清楚。
答案 0 :(得分:19)
在我的旧实验室上花了28秒。如果我有更多的处理器,它可能会快一点,但是大部分时间花在读取和写入文件上(15秒),这不会更快。
其中一个关键因素是缓存的大小。如果数据在缓存中,则比较本身非常便宜。由于L3缓存是共享的,因此您需要一个线程来充分利用它。
public static void main(String...args) throws IOException {
generateFile();
long start = System.currentTimeMillis();
int[] nums = readFile("numbers.bin");
Arrays.sort(nums);
writeFile("numbers2.bin", nums);
long time = System.currentTimeMillis() - start;
System.out.println("Took "+time+" secs to sort "+nums.length+" numbers.");
}
private static void generateFile() throws IOException {
Random rand = new Random();
int[] ints = new int[50*1000*1000];
for(int i= 0;i<ints.length;i++)
ints[i] = rand.nextInt();
writeFile("numbers.bin", ints);
}
private static int[] readFile(String filename) throws IOException {
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(filename), 64*1024));
int len = dis.readInt();
int[] ints = new int[len];
for(int i=0;i<len;i++)
ints[i] = dis.readInt();
return ints;
}
private static void writeFile(String name, int[] numbers) throws IOException {
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(name), 64*1024));
dos.writeInt(numbers.length);
for (int number : numbers)
dos.writeInt(number);
dos.close();
}
答案 1 :(得分:8)
在并行化和分发方面,merge sort似乎是最好的选择,因为它使用分而治之做法。有关详细信息,请参阅“并行合并排序”和“分布式合并排序”。
对于单机,多核示例,请参阅Correctly multithreaded quicksort or mergesort algo in Java?。如果您可以使用Java 7 fork / join,请参阅:“Java 7: more concurrency”和“Parallelism with Fork/Join in Java 7”。
对于在多台计算机上分发,请参阅Hadoop,它有一个分布式合并排序实现:请参阅MergeSort和MergeSorter。同样感兴趣:Hadoop Sorts a Petabyte in 16.25 Hours and a Terabyte in 62 Seconds
答案 2 :(得分:4)
对于排序而非许多元素,您的最佳镜头是Merge Sort。它通常是数据库使用的算法。尽管不如Quick Sort快,但它使用中间存储,因此您不需要大量内存来执行排序。
另外,正如sje397和Scott在评论中所指出的,Merge Sort是高度可并行化的。
答案 3 :(得分:3)
这在很大程度上取决于问题领域。例如,如果所有数字都是正数,则最好的方法是创建一个0-MAX_INT数组,然后计算每个数字在读取文件时出现的次数,然后用非打印出每个int零计数,但它发生了很多次。这是一个O(n)“排序”。这种官方名称,但我忘了它是什么。
顺便说一句,我在谷歌的一次采访中被问到了这个问题。从问题的限制我想出了这个解决方案,它似乎是他们正在寻找的答案。 (我拒绝了这份工作,因为我不想搬家。)
答案 4 :(得分:2)
他们不是那么多。如果它们是10字节长扩展,例如它将是500Mbytes的数组,它几乎可以留在我的手机上! ;) 所以,如果只是那样的话,我会去Quicksort。
答案 5 :(得分:2)
在我的机器上排序250 000 000个整数花了大约2分钟,所以去吧:)
答案 6 :(得分:0)
现在50e6的数字非常小,不要让事情变得比他们需要的更复杂......
bash$ sort < file > sorted.file