简体   繁体   English

java-如何使此计算更快?

[英]java - How can i make this calculation faster?

My function is total += Math.sqrt(num) - Math.cbrt(num); 我的功能是total += Math.sqrt(num) - Math.cbrt(num); I want to apply this to every number till the max value(starting from 0) i determine. 我想将此应用于每个数字,直到我确定最大值(从0开始)。 So i wrote some code below which uses divide technique to calculate faster. 因此,我在下面编写了一些代码,该代码使用除法技术更快地进行计算。 How can i fasten this calculation? 我怎样才能加快计算速度? Code below( 8 threads ) takes 20 seconds to finish while non-thread takes 150 seconds to finish. 下面的代码( 8个线程 )需要20秒才能完成,而非线程则需要150秒才能完成。 I believe with forkjoinpool i can make it faster or maybe parallel streams ? 我相信使用forkjoinpool可以使速度更快,或者可以parallel streams吗? How to implement it with them? 如何与他们一起实施?

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;
    }
}

Edit 1 编辑1

futureList.get(a).get(); i had to do that in that way because i don't know the thread(core) count. 我必须那样做,因为我不知道线程(核心)的数量。 Thus i can not write futureList.get(0).get() + futureList.get(1).get()..... I know till futureList.get(0).get() loop will wait but still they will be doing their job. 因此,我无法编写futureList.get(0).get()+ futureList.get(1).get().....我知道直到futureList.get(0).get()循环将等待,但仍然将做他们的工作。 My thread count is not fixed and can change any moment. 我的线程数不固定,可以随时更改。

MultiThreading can benefit when your application is I/O intensive. 当您的应用程序是I / O密集型时,多线程可以受益。 However, this application is computing sensitive, maybe assign threadCount the number of your processor is best choice: 但是,此应用程序对计算很敏感,也许为您的处理器编号分配threadCount是最佳选择:

private static int threadCount = Runtime.getRuntime().availableProcessors();
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;
    }
}

Just a thought. 只是一个想法。 Let's discuss to optimize it more. 让我们讨论一下对其进行更多优化。

How to reduce your calculation to 1 microsecond? 如何将计算减少到1微秒? Easy. 简单。

Your grand total is : sum of the n square roots - sum of the n cubic roots 您的总计是:n个平方根的总和-n个立方根的总和

Math tips : 数学技巧:

double sumOfSquareRoots = 2D * Math.pow((n + 0.5D), 1.5D) / 3D - 0.22474487139;

See https://arxiv.org/pdf/1204.0877.pdf for cubic roots :) https://arxiv.org/pdf/1204.0877.pdf立方根:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM