Home > Enterprise >  Why do two tasks take much longer if running in multithreading than in mono threading?
Why do two tasks take much longer if running in multithreading than in mono threading?

Time:12-24

I wrote this Java method which takes about one second to run (on my computer):

    /**
     * This method takes about one second to run.
     */
    private long eseguiUnitàDiLavoro() {
        double x, y = 1000;
        final long start_time, stop_time;

        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000000; i  ) {
            x = Math.random();
            y = y / Math.atan(x);
        }
        stop_time = System.currentTimeMillis();
        return stop_time - start_time;
    }

If I run that method five times (L0, L1, L2, L3, L4) I get these times:

  • L0 takes 1099 ms,
  • L1 takes 1114 ms,
  • L2 takes 1099 ms,
  • L3 takes 1098 ms,
  • L4 takes 1100 ms.

And the overall execution time is 5510 ms (about five times the time that each task takes). And this is fine.

But if I build that method as a thread, and I run it five times, I get these times:

  • L0 takes 15729 ms,
  • L1 takes 15635 ms,
  • L2 takes 15557 ms,
  • L3 takes 15714 ms,
  • L4 takes 15604 ms.

The overall execution time is now 15745 ms.

The tasks execution order is now L1 L2 L4 L3 L0, and this is fine.

But I expected the overall execution time was the same in both cases. Conversely when the multithreading approach was used, it was about three times slower than the mono threading one.

I expected the multithreading approach was slightly slower than mono threading (due to some scheduler overhead) but three times slower is too much for me. What did I misunderstand?

I also expected that the tasks L0, L1, L2, ... each took about 5 seconds and they, started together, stopped together too. In fact, they started together and stopped together, but each took about fifteen seconds.

Can someone explain to me why multithreading processing is so inefficient? Thank you all

CodePudding user response:

There are lots of possible explanations, including that you coded the multithreading solution wrong, but the one that jumps out at me is that Math.random() is fully synchronized and can't be run concurrently. Its documentation actually calls this out:

However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.

Using ThreadLocalRandom or separate Random objects instead of Math.random() would address that concern.

In general, though, this is likely to be about your code, not about multithreading in general. (Other possibilities that occur to me include how you're measuring the time consumption and how many cores are actually available on your machine.)

  • Related