非同期処理が同期処理より遅いことについて理解したい


現在Javaで非同期処理を勉強しています。CompletableFutureを見ています。

以下のようなコードを書いたのですが、非同期処理より同期処理の方が速くなります。  
簡単な処理だからでしょうか？初期化や設定に時間がかかるため今回は同期処理の方が速くなったのでしょうか？  
またどういった処理あたりから非同期処理の方が速くなるのでしょうか？  
明確な違いではなく、ご経験からの感想やご意見で構いません。よろしくお願いいたします。

[code]

    public class CompletableFutureSample {
        public static void main(String[] args) {
    
            long start = System.currentTimeMillis();
    
            CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(() -> 1 * 100 * 35 * 42 * 75);
            CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> 2 * 100 * 35 * 42 * 75);
    
            cf.thenAcceptBoth(cf2, (c1, c2) -> {
                System.out.println("cf :" + c1 + ", cf2 : " + c2);
                System.out.println("result : " + (c1 + c2));
            });
    
            //      Integer i1 = 1 * 100 * 35 * 42 * 75;
            //      Integer i2 = 2 * 100 * 35 * 42 * 75;
            //
            //      System.out.println("cf :" + i1 + ", cf2 : " + i2);
            //      System.out.println("result : " + (i1 + i2));
    
            long end = System.currentTimeMillis();
            System.out.println((end - start) + "ms");
    
        }
    }
    
[/code]

非同期（コメントなし箇所）  
cf :11025000, cf2 : 22050000  
result : 33075000  
134ms

同期（コメントアウト箇所）  
cf :11025000, cf2 : 22050000  
result : 33075000  
1ms




> 簡単な処理だからでしょうか？初期化や設定に時間がかかるため今回は同期処理の方が速くなったのでしょうか？

そうだと思います。  
今回のケースでは、準備にかかる時間と比較して、計算に使った時間は無視できるほど短いと思います。  
非同期処理に134msかかっていますが、ほとんど準備に使われていると思います。

> またどういった処理あたりから非同期処理の方が速くなるのでしょうか？

入出力待ちなど、CPUの実行権を放棄する処理を並行する場合に効果が出ると考えます。ただし、CPUの実行権を放棄する時間が準備に要する時間より短い場合、効果は期待できません。

なお、大量にCPUを使う計算処理の場合は、CPUの数によっては非同期処理の効果が出ると思います。




非同期は計算資源が豊富にあって、プロセスに長い処理と短くて回数のある処理を流したい場合に有効ですよね。これは、長い処理がリソースを占有し、短い処理がそれを待つということをするからです。この場合、両者に依存がなければ、非同期とすることでリソースを有効活用できますが、管理コストが乗ってきます。仮に短くてリソースを占有しない処理を非同期としても短くなるどころか管理コストだけ増えてかえって遅くなることも想定されます。ご呈示の処理は管理コストに見合うものでしょうか。とても軽くてあまり効果が出ないような処理に見えます。それぞれの処理でどういったスレッド構成になっているかなど、frightrecorderやvisual
vmを利用して観察すると面白いかと思います。

また、一回だけの計測ではその他の要因（たとえば、同一PCで走っている別のプロセスへのリソース割り当て）に影響されるので、複数回とって平均を観察するなどされると精度の良いデータが得られるのではないでしょうか。（すでにやっていらっしゃるのかもしれませんが。）

それと、非同期自体を「早くするため」に使うよりも「とりあえず応答しておく」ために使ったりすることも知っておくと面白いかもしれません。

