我的函数是total += Math.sqrt(num) - Math.cbrt(num);
我想将它应用于每个数字,直到我确定的最大值(从0开始)。所以我在下面编写了一些代码,使用除法技术来更快地计算。我怎样才能加快这个计算?下面的代码( 8个帖子)需要 20秒才能完成,而非线程需要 150秒才能完成。我相信forkjoinpool
我可以让它更快或者parallel streams
?如何用它们实现它?
public class Main {
private static int targetNum = Integer.MAX_VALUE;
private static int threadCount = 8;
private static double total = 0;
public static void main(String[] args) {
// write your code here
DecimalFormat df2 = new DecimalFormat(".##");
long time = System.currentTimeMillis();
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
try {
ArrayList<Future<Double>> futureList = new ArrayList<>();
for(int a = 0; a < threadCount; a++){
calculatorService ss = new calculatorService(a*(targetNum/threadCount) ,(a+1) *(targetNum/threadCount));
futureList.add(executor.submit(ss));
}
for(int a = 0; a < threadCount; a++){
total+= futureList.get(a).get();
}
System.out.println("Result= "+ df2.format(total) + "\nTime passed= " + ((System.currentTimeMillis() - time)/1000f));
executor.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class calculatorService implements Callable<Double>{
private int start,end;
public SqrtSummer(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public Double call(){
double total = 0;
for (int a = start; a < end; a++) {
total += Math.sqrt(a) - Math.cbrt(a);
}
return total;
}
}
修改1
futureList.get(a).get();
我必须这样做,因为我不知道线程(核心)计数。因此我不能写futureList.get(0).get()+ futureList.get(1).get().....我知道,直到futureList.get(0).get()循环将等待,但他们仍然将会做他们的工作。我的线程数不固定,可以随时改变。
答案 0 :(得分:3)
当您的应用程序是I / O密集型时,MultiThreading可以从中受益。但是,此应用程序对计算敏感,可能指定threadCount
处理器的数量是最佳选择:
private static int threadCount = Runtime.getRuntime().availableProcessors();
答案 1 :(得分:0)
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
private static int targetNum = Integer.MAX_VALUE;
private static int threadCount = Runtime.getRuntime().availableProcessors();
private static double total = 0;
public static void main(String[] args) {
// write your code here
DecimalFormat df2 = new DecimalFormat(".##");
long time = System.currentTimeMillis();
List<Future<Double>> futureList = new ArrayList<>();
int lastSize=futureList.size();
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
Runnable sumRunnable= () ->
{ int sumCalculatedTill=0;
while(!executor.isTerminated())
{
if(lastSize!=futureList.size())
{
for(int i=sumCalculatedTill;i<futureList.size();i++)
try {
total+=futureList.get(i).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sumCalculatedTill=futureList.size();
}
}
System.out.println("Result= "+ df2.format(total) + "\nTime passed= " + ((System.currentTimeMillis() - time)/1000f));
};
Thread thread=new Thread(sumRunnable);
thread.start();
try {
for(int a = 0; a < threadCount; a++){
calculatorService ss = new calculatorService(a*(targetNum/threadCount) ,(a+1) *(targetNum/threadCount));
futureList.add(executor.submit(ss));
}
/*for(int a = 0; a < threadCount; a++){
total+= futureList.get(a).get();
}
*/
executor.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class calculatorService implements Callable<Double>{
private int start,end;
public calculatorService(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public Double call(){
double total = 0;
for (int a = start; a < end; a++) {
total += Math.sqrt(a) - Math.cbrt(a);
}
return total;
}
}
只是一个想法。让我们讨论更多优化它。
答案 2 :(得分:0)
如何将计算减少到1微秒?容易。
你的总数是:n平方根的总和 - n立方根的总和
数学提示:
double sumOfSquareRoots = 2D * Math.pow((n + 0.5D), 1.5D) / 3D - 0.22474487139;
请参阅https://arxiv.org/pdf/1204.0877.pdf了解立方根:)