0

I'm trying to create 100k virtual threads with simple print statements. When I use the below code, the estimated execution time is 2 milliseconds:

List < Thread > threads = IntStream.of(0, 100000)
  .mapToObj(it -> Thread.ofVirtual().unstarted(() -> System.out.println(Thread.currentThread())))
  .toList();

long begin = System.currentTimeMillis();
threads.forEach(Thread::start);
for (Thread thread: threads) {
  thread.join();
}
long end = System.currentTimeMillis();
System.out.println("time taken: " + (end - begin) + " milliseconds");

But, when I use a for loop instead of IntStream, the estimated execution time is 6925 milliseconds.

List < Thread > threads = new ArrayList < > ();
for (int i = 0; i < 100000; i++) {
  threads.add(Thread.ofVirtual().unstarted(() -> System.out.println(Thread.currentThread())));
}

long begin = System.currentTimeMillis();
threads.forEach(Thread::start);
for (Thread thread: threads) {
  thread.join();
}
long end = System.currentTimeMillis();
System.out.println("time taken: " + (end - begin) + " milliseconds");

I know that IntStream is more memory efficient than regular for loops. But, as per my understanding, IntStream doesn't do anything magical compared to a for loop. So, I'm wondering why there's a big gap in the performance above. I'm running this experiment in an 8 core Mac machine.

Update: IntStream.of() takes only two numbers above and those are not the range of numbers. So, it is incorrect.

I removed the print statements and used a HashSet to track the number of platform threads used. After making the corrections, the estimated execution time to create 100k virtual threads using both for loop and IntStream.range() is around 150 milliseconds in my 8 core system.

Adding print statements added lot of overheads as you can see from previously shared results.

Rahul Raj
  • 3,197
  • 5
  • 35
  • 55
  • 4
    Add size of threads array to the system out at the end to have an idea what is wrong. To make these two examples equivalent, change `IntStream.of()` to `IntStream.range()`. – Maciej Walkowiak Apr 23 '23 at 18:42
  • 2
    The way you're measuring performance will produce outright lies, but Maciej's point is even more relevant. – Louis Wasserman Apr 23 '23 at 19:10
  • @MaciejWalkowiak Thanks for point out the mistake there. I was thinking that those are range of numbers! – Rahul Raj Apr 24 '23 at 03:27
  • @LouisWasserman I have corrected the mistake as Maciej pointed out. But, otherwise what do you suggest to measure the execution performance? profiling? I will not draw generic conclusion from my 8-core system. The intent here is to evaluate virtual threads in general. – Rahul Raj Apr 24 '23 at 04:02
  • 2
    If you want meaningful performance comparisons, you pretty much _must_ use JMH. Subtracting System.currentTimeMillis can produce results that are outright wrong even for your system. – Louis Wasserman Apr 24 '23 at 04:46
  • 1
    Don’t insert the answer into your question. Post an answer instead. – Holger Apr 25 '23 at 07:11
  • @Holger stackoverflow doesn't let you answer your own question for first 24 hours. You must be knowing it already. And later on, I didn't get time on creating a post here. I will do it. – Rahul Raj Apr 27 '23 at 07:00

0 Answers0