在陣列中搜索數字的正常方法:
public class Search {
public static boolean search(int x, int [] arr) {
for (int i : arr) {
if (x == i) {
return true;
}
}
return false;
}
}
我的多執行緒方式:
import java.util.concurrent.RecursiveTask;
public class SearchAsync extends RecursiveTask<Boolean> {
private static final int CUTOFF = 8;
private final int x;
private final int[] arr;
private final int lo, hi;
private SearchAsync(int x, int[] arr) {
this(x, arr, 0, arr.length - 1);
}
private SearchAsync(int x, int[] arr, int lo, int hi) {
this.x = x;
this.arr = arr;
this.lo = lo;
this.hi = hi;
}
public static boolean search(int x, int[] arr) {
return new SearchAsync(x, arr).compute();
}
protected Boolean compute() {
if (hi - lo < CUTOFF) {
return computeSync();
}
int mid = (lo hi) >> 1;
SearchAsync sa1 = new SearchAsync(x, arr, lo, mid);
sa1.fork();
SearchAsync sa2 = new SearchAsync(x, arr, mid 1, hi);
return sa2.compute() || sa1.join();
}
private boolean computeSync() {
for (int i = lo; i <= hi; i ) {
if (x == arr[i]) {
return true;
}
}
return false;
}
}
現在測驗類:
public class Test {
private static final int MAGIC_NUMBER = 69;
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] arr = new int[n];
int iter = Integer.parseInt(args[1]);
long start = System.currentTimeMillis();
for (int i = 0; i < iter; i ) {
Search.search(MAGIC_NUMBER, arr);
}
long end = System.currentTimeMillis();
System.out.println((end - start) / 1_000.0);
}
}
public class TestAsync {
private static final int MAGIC_NUMBER = 69;
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] arr = new int[n];
int iter = Integer.parseInt(args[1]);
long start = System.currentTimeMillis();
for (int i = 0; i < iter; i ) {
SearchAsync.search(MAGIC_NUMBER, arr);
}
long end = System.currentTimeMillis();
System.out.println((end - start) / 1_000.0);
}
}
對一個大陣列運行這些測驗,讓我們說 10 次:
gursimarmiglani@Gursimars-MacBook-Pro multithread % java Test 1000000000 10
1.924
gursimarmiglani@Gursimars-MacBook-Pro multithread % java TestAsync 1000000000 10
6.311
我猜多執行緒是遞回的,并且分叉了太多行程。如果你去 JDK 17's API page on RecursiveTask 有一個計算斐波那契函式的例子,我基本上把它的格式復制到這里。如何改進多執行緒呢?
uj5u.com熱心網友回復:
我要做的第一件事是使用 JMH 進行適當的基準測驗,然后再查看問題。JMH 將處理一些明顯的基準測驗問題,如預熱、多次運行以提高可靠性以及如果正確完成死代碼消除。除此之外,它還可以讓您訪問一組內置的分析器。
我認為你的截止日期太低了。為每個 CPU 提供大量線性記憶體以供掃描(至少幾 KB,但可能更高)。這不僅會減少 FJ 的開銷,還會給 CPU 一些空間來發揮它的魔力。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/391055.html
上一篇:Python多處理一個類
下一篇:Parallel.ForEach:Break和ParallelLoopState.LowestBreakIteration。該怎么辦?
