Interesting Benchmarks
    Eric Kolotyluk 
    eric at kolotyluk.net
       
    Tue Nov  9 21:20:31 UTC 2021
    
    
  
Okay, after correcting some code mistakes, my latest benchmarks are
* Benchmark                                     tested  throughput   ratio
* PrimeThreads.platformPrimesTo_1000               500       4.098   0.274
* PrimeThreads.platformPrimesTo_10_000           5,000       5.068   0.054
* PrimeThreads.platformPrimesTo_10_000_000   5,000,000       4.791   0.032
* PrimeThreads.virtualPrimesTo_1000                500      14.961   3.651
* PrimeThreads.virtualPrimesTo_10_000            5,000      93.500  18.449
* PrimeThreads.virtualPrimesTo_10_000_000    5,000,000     151.248  31.569
This is based on
public static void futurePrimes22(long limit, ThreadFactory threadFactory) {
    try (var executorService =
Executors.newThreadPerTaskExecutor(threadFactory)) {
        var tasks = LongStream.iterate(3, x -> x < limit, x -> x + 2)
                .mapToObj(candidate -> {
                    return executorService.submit(() ->
isPrime(candidate, 10, 30) ? candidate : null);
                }).collect(Collectors.toList());
        var result = tasks.stream().filter(x -> {
            try {
                return x.get() != null;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            return false;
        });
    }
}
and
static boolean isPrime(long candidate, long minimumLag, long maximumLag) {
    BinaryOperator<Long> lag = (minimum, maximum) -> {
        if (minimum <= 0 || maximum <= 0) return 0L;
        var approx = (long) Math.nextUp(Math.sqrt(maximum - minimum));
        try {
            var approximateLag = minimum + approx;
            Thread.sleep(approximateLag);
            return approximateLag;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            return 0L;
        }
    };
    lag.apply(minimumLag, maximumLag);  // Simulate network request overhead
    if (candidate == 2) return true;
    if ((candidate & 1) == 0) return false; // filter out even numbers
    var limit = (long) Math.nextUp(Math.sqrt(candidate));
    for (long divisor = 3; divisor <= limit; divisor += 2) {
        // Thread.onSpinWait(); // If you think this will help, it likely won't
        if (candidate % divisor == 0) return false;
    }
    lag.apply(minimumLag, maximumLag);  // Simulate network response overhead
    return true;
}
where I vary limit and threadFactory.
So, I am trying to understand Ignaz's observation that I would not be
launching 5,000,000 threads at once because I am using
newThreadPerTaskExecutor(), because I want to be able to explain this to
others. Given that the first thing isPrime() does is call threadSleep() for
10 to 30 ms, wouldn't that give newThreadPerTaskExecutor() a chance to ramp
up a lot of threads? Is there something that limits the number of threads
that will be started? Is 10 - 30 ms too short to start that many threads?
Sorry if I seem a little naive, but I want to understand.
Cheers, Eric
On Mon, Nov 8, 2021 at 8:19 PM Eric Kolotyluk <eric at kolotyluk.net> wrote:
> Thanks for the insights Ignaz...
>
> Yes, I am using Executors.newThreadPerTaskExecutor(threadFactory), but I
> am new to this API. At this point, I don't really care if I did have
> 5,000,000 Platform Threads running, only wanted to compare the throughput
> of Platform Threads to Virtual Threads. If you are suggesting this was not
> a good experiment, I want to correct that.
>
> I can see now some more mistakes I made, so will have to rerun the
> benchmarks again.
>
> Cheers, Eric
>
>
>
>
>
> On Mon, Nov 8, 2021 at 12:50 PM Ignaz Birnstingl <ignazb at gmail.com> wrote:
>
>> Hi Eric,
>>
>> > I would
>> > not have thought it possible to run 5,000,000 Platform Threads.
>>
>> As far as I can tell by looking at your code you didn't. I think you
>> submit the tasks sequentially to an ExecutorService created with
>> Executors.newThreadPerTaskExecutor(). This causes many tasks (=threads)
>> to
>> end before the last one is submitted.
>>
>> I would suggest you use a different (thread caching) ExecutorService for
>> platform threads. Otherwise you are mainly measuring thread creation
>> time
>> of virtual threads vs platform threads.
>>
>> Ignaz
>>
>
    
    
More information about the loom-dev
mailing list