簡體   English   中英

java - 多線程中的簡單計算比單線程需要更長的時間

[英]java - Simple calculation takes longer in multi threads than in single thread

我試圖了解如何利用多線程。 我寫了一個簡單的程序,使用兩種方式增加i的值,比如400,000次:單線程方式(0到400,000)和多線程方式(在我的情況下,4次:0到100,000)線程等於Runtime.getRuntime().availableProcessors()

我對我測量的結果感到驚訝:單線程方式明顯更快,有時快3倍。 這是我的代碼:

public class Main {
    public static int LOOPS = 100000;
    private static ExecutorService executor=null;

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        int procNb = Runtime.getRuntime().availableProcessors();
        long startTime;
        long endTime;

        executor = Executors.newFixedThreadPool(procNb);
        ArrayList<Calculation> c = new ArrayList<Calculation>();

        for (int i=0;i<procNb;i++){
            c.add(new Calculation());
        }

        // Make parallel computations (4 in my case)
        startTime = System.currentTimeMillis();
        queryAll(c);
        endTime = System.currentTimeMillis();

        System.out.println("Computation time using " + procNb + " threads : " + (endTime - startTime) + "ms");

        startTime = System.currentTimeMillis();
        for (int i =0;i<procNb*LOOPS;i++)
        {

        }
        endTime = System.currentTimeMillis();
        System.out.println("Computation time using main thread : " + (endTime - startTime) + "ms");
    }

    public static List<Integer> queryAll(List<Calculation> queries) throws InterruptedException, ExecutionException {
        List<Future<Integer>> futures = executor.invokeAll(queries);
        List<Integer> aggregatedResults = new ArrayList<Integer>();
        for (Future<Integer> future : futures) {
            aggregatedResults.add(future.get());
        }
        return aggregatedResults;
    }

}

class Calculation implements Callable<Integer> {

    @Override
    public Integer call() {
        int i;
        for (i=0;i<Main.LOOPS;i++){
        }
        return i;
    }
}

安慰 :

Computation time using 4 threads : 10ms. Computation time using main thread : 3ms.

有人能解釋一下嗎?

一個加法可能需要一個cpu周期,所以如果你的cpu以3GHz運行,那就是0.3納秒。 做它400k次,變成120k納秒或0.1毫秒。 因此,您的測量更多地受到啟動線程,線程切換,JIT編譯等的開銷的影響,而不是您嘗試測量的操作。

您還需要考慮編譯器優化:如果將空循環放在方法中並多次運行該方法,您會注意到它在一段時間后在0毫秒內運行。 因為編譯器確定循環不執行任何操作並完全優化它。

我建議您使用專門的庫進行微基准測試,例如jmh

另請參閱: 如何在Java中編寫正確的微基准測試?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM