Java 排序50000个数字

Java 排序50000个数字,java,algorithm,sorting,parallel-processing,Java,Algorithm,Sorting,Parallel Processing,假设我们需要对50000个数字进行排序。假设这些数字存储在一个文件中。解决这个问题最有效的算法是什么?排序的并行算法 怎么做?可能是有用的链接) 我不能使用标准算法,因此我向您询问方法和算法:) 好的。。我读到了关于并行合并排序。。。但我不清楚 解决方案,第一版 对于排序比许多元素都多的元素,您的最佳选择是。它通常是数据库使用的算法。尽管速度不如,但它使用中间存储,因此不需要大量内存来执行排序 此外,正如sje397和Scott在评论中指出的,合并排序是高度并行的。它在很大程度上取决于问题域。例

假设我们需要对50000个数字进行排序。假设这些数字存储在一个文件中。解决这个问题最有效的算法是什么?排序的并行算法

怎么做?可能是有用的链接)

我不能使用标准算法,因此我向您询问方法和算法:)

好的。。我读到了关于并行合并排序。。。但我不清楚

解决方案,第一版

对于排序比许多元素都多的元素,您的最佳选择是。它通常是数据库使用的算法。尽管速度不如,但它使用中间存储,因此不需要大量内存来执行排序


此外,正如sje397和Scott在评论中指出的,合并排序是高度并行的。

它在很大程度上取决于问题域。例如,如果所有数字都是正整数,最好的方法可能是创建一个0-MAX_INT数组,然后在读取文件时计算每个数字出现的次数,然后以非零计数打印每个整数,无论出现的次数如何。这是一个O(n)“排序”。那种东西有一个正式的名字,但我忘了它是什么

顺便说一下,我在谷歌的采访中被问到这个问题。根据问题的限制条件,我提出了这个解决方案,这似乎是他们想要的答案。(我拒绝了这份工作,因为我不想搬家。)

从我的角度来看,在并行化和分布方面,似乎是最好的选择,因为它使用了分而治之的方法。有关更多信息,请使用谷歌搜索“并行合并排序”和“分布式合并排序”

有关单机、多核的示例,请参阅。如果您可以使用Java7 fork/join,请参阅:“和”


有关在多台机器上分发它的信息,请参见,它有一个分布式合并排序实现:请参见和。同样有趣的是:

它们并不多。如果它们是10字节长的扩展,例如,它将是一个500字节的数组,它几乎可以留在我的手机上
因此,如果只是这样的话,我会说选择快速排序。

5000万不是特别大。我会把它们读入记忆。把它们分类并写出来。这应该只需要几秒钟。你需要多快?您需要它的编译程度如何

在我的旧labtop上花了28秒。如果我有更多的处理器,它可能会快一点,但大部分时间都花在读写文件上(15秒),这不会更快


关键因素之一是缓存的大小。如果数据在缓存中,比较本身就非常便宜。由于三级缓存是共享的,因此您只需要一个线程就可以充分利用它

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();
}
publicstaticvoidmain(String…args)抛出IOException{
生成文件();
长启动=System.currentTimeMillis();
int[]nums=readFile(“numbers.bin”);
数组。排序(nums);
writeFile(“numbers2.bin”,nums);
长时间=System.currentTimeMillis()-启动;
System.out.println(“用“+时间+”秒对“+nums.length+”数字进行排序”);
}
私有静态void generateFile()引发IOException{
Random rand=新的Random();
int[]ints=新的int[50*1000*1000];

对于(int i=0;i不要害怕大的数字。事实上,50000个数字并没有那么大。因此,如果这些数字是整数,那么每个数字的大小是4字节,因此需要为这个数组分配的总内存是50000*4/1024/1024=190.7兆字节,这是相对较小的。完成数学运算后,您可以继续进行QuickSor注意.net数组中的内置排序方法使用快速排序,我不确定java中是否也是这样


在我的机器上排序25万个整数大约需要2分钟,所以开始吧:)

50e6数字现在非常小,不要让事情变得比需要的更复杂


bash$sortsorted.file

和MergeSort很容易并行化。Merge-sort也非常可并行化……而sje397和我的波长完全相同。:-)@斯科特-也有相同的名字;)当然,如果你有太字节的数据要排序,我会这么做。:)找不到多核系统的精确算法。也许你可以提供一些链接或论文?@Paul He只是来自矩阵-看看他的昵称:)你为什么不能使用标准算法?这是一个家庭作业问题吗?还有,什么类型的数字这些?整数?是有界的吗?更多的信息会非常有帮助:)约翰:类似的)但更重要的是),是的,数字)int[]a=new int[50000000];:)在现代处理器上,对5000万个数字进行排序时,并行算法是多余的。标准串行处理的工作量很小,甚至考虑到文件I/O时间,也就是说,整个任务不应该超过一分钟,其中大部分是文件I/O.50000*4(couse sizeof(item)==4)=200×000 000μm。你应该乘以4,不分。50m的值在4字节中每个都要花费200兆字节(二进制税后的19MB)。“因为L3缓存是共享的,一个线程就是你需要充分利用它的。”然而,我的C++代码占用6S(时钟和CPU)。在一个线程中对50万个整数进行排序,3.7秒时钟/6.5秒CPU首先将整数划分为INT_MAX的上下两部分,然后在一个线程中对下半部分进行排序,在另一个线程中对上半部分进行排序。不知道Java是否会有所不同,但表明L3缓存并不是它的全部。这是使用均匀分布的值。只是计时而已在我的笔记本电脑上,一个线程占用了13秒,两个线程占用了7秒。虽然这节省了6秒(占总数的22%),但这大大增加了代码的复杂性(未发布;)请注意,对于6个内核,我可以再节省5秒,但仍然需要18秒,因为加载和保存需要15秒。这很大程度上取决于保存fe的重要性