【问题标题】:Quicksort Multithreading快速排序多线程
【发布时间】:2018-06-24 14:56:11
【问题描述】:

我想为具有多线程的二维数组实现快速排序算法。

它在单线程中工作得非常快,但现在我试图加快它的速度。这是我对二维数组的每一部分进行正确排序的代码(排序算法本身的速度应该很快)。它直接作用于“c”。

public static void sort(int[][] c) {
    int[][] a = new int[][] { { 0, -4, 1, 2 }, { 1, 0, 3 }, { 2, 3, 0 } };
    for (int i = 0; i < c.length; i++) {
        sort(c[i],0,c[i].length-1);
    }

}

我想知道: 将 for 循环拆分为执行“x”个循环任务的小型“循环器”,但这会减慢算法速度。

有人可以帮我加快速度吗?

【问题讨论】:

  • 关于测试的元素有多少?
  • 数组类似于 [100_000] [75] 大小

标签: java performance loops for-loop


【解决方案1】:

几种可能性:

public static void sort(int[][] c) {
    for (int i = 0; i < c.length; i++) {
        //sort(c[i],0,c[i].length-1);
        Arrays.sort(c[i]);
    }
}

public static void parallelSort(int[][] c) {
    Arrays.asList(c).parallelStream().forEach(d -> Arrays.sort(d));
}

public static void threadedSort(int[][] c) throws InterruptedException {
    int count = 4;
    Thread[] threads = new Thread[count];
    for (int i = 0; i < count; i++) {
        final int finalI = i;
        threads[i] = new Thread(
                () -> sortOnThread(c, (c.length / count) * finalI, c.length / count), 
                "Thread " + i
            );
        threads[i].start();
    }
    for (Thread thread : threads) {
        thread.join();
    }
}

private static void sortOnThread(int[][] c, int first, int length) {
    for (int i = first; i < first + length; i++) {
        Arrays.sort(c[i]);
    }
}

public static void main(String[] args) throws InterruptedException {
    int[][] c = new int[10_000_000][75];

    shuffle(c);
    System.out.println("Starting sort()");
    long before = System.currentTimeMillis();
    sort(c);
    System.out.println("Took " + (System.currentTimeMillis() - before) + "ms");

    shuffle(c);
    System.out.println("Starting parallelSort()");
    before = System.currentTimeMillis();
    parallelSort(c);
    System.out.println("Took " + (System.currentTimeMillis() - before) + "ms");

    shuffle(c);
    System.out.println("Starting threadedSort()");
    before = System.currentTimeMillis();
    threadedSort(c);
    System.out.println("Took " + (System.currentTimeMillis() - before) + "ms");
}

private static void shuffle(int[][] c) {
    for (int i = 0; i < c.length; i++) {
        for (int j = 0; j < c[i].length; j++)
            c[i][j] = j;
        Collections.shuffle(Arrays.asList(c[i]));
    }
}

在四核 (i5-2430M) 上产生这些计时:

Starting sort()
Took 2486ms
Starting parallelSort()
Took 984ms
Starting threadedSort()
Took 875ms

parallelStream() 方法的代码最少,但与直接线程相比,显然会带来更多开销(通过ForkJoinPool 发送每个排序)。当数组较小时,这一点更加明显[100_000] [75]

Starting sort()
Took 48ms
Starting parallelSort()
Took 101ms
Starting threadedSort()
Took 21ms

以防万一它有用......最初在编码时,我发现这三种方法的时间更加相似:

Starting sort()
Took 2403ms
Starting parallelSort()
Took 2435ms
Starting threadedSort()
Took 2284ms

这原来是因为我每次都在我的 shuffle() 方法中天真地分配新的子数组。显然,这会产生大量额外的 GC 工作——即使是在调用排序方法之前的短暂睡眠也会产生重大影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2021-03-11
    • 1970-01-01
    • 2011-10-25
    • 2017-12-26
    • 1970-01-01
    相关资源
    最近更新 更多