Write a shell sort that uses multithreading

When I looked at various sorting algorithms a few days ago, I was deeply impressed by Hill sorting: just dividing the array into multiple parts and sorting them separately is much faster than the ordinary insertion sort. I was sighing and wondered if we could use a multi-threaded method. If it is feasible to calculate different groupings in Hill sorting in parallel, wouldn't the efficiency be improved a lot, so it took some time to write a multi-threaded implementation, which is recorded here.

Original Hill Sort

The original Shell sort, from "Algorithms (4th Edition)"

```public class ShellSort {

public static void sort(Comparable[] a){
int key = 1;
int length = a.length;

while(key < length/3){
key = key*3 + 1;
}
while(key != 1) {
key = key/3;

for(int i = 1 ; i<=key; i++){
for(int j = i; j<length ;j=j+key){
for(int m =j ; m>=0 && m-key >= 0 && SortingTool.less(a[m], a[m-key]); m= m-key)
SortingTool.exch(a,m,m-key);
}
}
}
}

}```

Tools

```import java.security.SecureRandom;

public class SortingTool {

private static final SecureRandom RANDOM = new SecureRandom();

public static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}

public static void exch(Comparable[] a, int i , int j){
Comparable t =  a[i];
a[i] = a[j];
a[j] = t;
}

public static Integer[] geneIntArr(int size) {
Integer[] result = new Integer[size];
for(int i = 0; i<result.length; i++){
result[i] = RANDOM.nextInt();
}
return result;
}

public static boolean isSort(Comparable[] a){
for(int i = 0 ; i<a.length - 1 ;i++){
if(less(a[i+1], a[i]))
return false;
}
return true;
}
}```

```public class ParallelShellSort {

public static void sort(Comparable[] a) {

ExecutorService service = Executors.newWorkStealingPool();
int k = 1;
int length = a.length;

while (k < length / 3) {
k = k * 3 + 1;
}
while (k != 1) {
k = k / 3;
/**
* For the same k value, k threads operate different parts of the array at the same time, and there is no intersection, so there is no problem of inconsistency in reading and writing,
* However, for different k values, the same position of the array may be operated by multiple threads at the same time, and there will be inconsistencies in reading and writing.
* For example, k=333, a thread has not completed processing, and if it enters the next iteration k=111, another thread may have problems with the thread that was not completed before.
* So for each k, use CountDownLatch to ensure that after k threads have completed the operation, enter the next round of iteration.
*/
CountDownLatch latch = new CountDownLatch(k);
for (int i = 1; i <= k; i++) {
service.submit(new ParallelShellSortRunnable(a, i, k, latch));
}
try {
latch.await();
} catch (InterruptedException e) {
System.out.println("err.." + e.getMessage());
}
}
service.shutdown();
try {
service.awaitTermination(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.out.println("error...");
}
}
}```

```public class ParallelShellSortRunnable implements Runnable{

private Comparable[] a;
private int start;
private int k;
private CountDownLatch latch;
public ParallelShellSortRunnable(Comparable[] a , int start, int k, CountDownLatch latch){
this.a = a;
this.start = start;
this.k = k;
this.latch = latch;
}
@Override
public void run() {
int length = a.length;

for(int j = start; j<length ;j=j+ k){
for(int m = j; m>=0 && m- k >= 0 && SortingTool.less(a[m], a[m- k]); m= m- k)
SortingTool.exch(a,m,m- k);
}
latch.countDown();
}
}```

测试和分析

arrayParallelSort，500000数据,耗时200毫秒

arrayParallelSort，500000数据,耗时218毫秒

arrayParallelSort，500000数据,耗时213毫秒

arrayParallelSort，500000数据,耗时231毫秒

arrayParallelSort，500000数据,耗时224毫秒

arrayParallelSort，2000000数据,耗时674毫秒

arrayParallelSort，2000000数据,耗时780毫秒

arrayParallelSort，2000000数据,耗时732毫秒

arrayParallelSort，2000000数据,耗时739毫秒

arrayParallelSort，2000000数据,耗时764毫秒

parallelShell，500000数据,耗时287毫秒

parallelShell，500000数据,耗时310毫秒

parallelShell，500000数据,耗时313毫秒

parallelShell，500000数据,耗时278毫秒

parallelShell，500000数据,耗时369毫秒

parallelShell，2000000数据,耗时705毫秒

parallelShell，2000000数据,耗时663毫秒

parallelShell，2000000数据,耗时785毫秒

parallelShell，2000000数据,耗时746毫秒

parallelShell，2000000数据,耗时755毫秒

300万数据,耗时906毫秒

300万数据,耗时242毫秒

300万数据,耗时256毫秒

300万数据,耗时236毫秒

300万数据,耗时265毫秒

300万数据,耗时1189毫秒

300万数据,耗时1131毫秒

300万数据,耗时1086毫秒

300万数据,耗时1076毫秒

300万数据,耗时1133毫秒

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327067075&siteId=291194637
Recommended
Ranking
Daily