Alex Rivera | Logout

Java vs C# Multithreading performance, why is Java getting slower? (graphs and full code included)

Asked 2012-04-05T11:32:14.347
12

I have recently been running benchmarks on Java vs C# for 1000 tasks to be scheduled over a threadpool. The server has 4 physical processors, each with 8 cores. The OS is Server 2008, has 32 GB of memory and each CPU is a Xeon x7550 Westmere/Nehalem-C.

In short, the Java implementation is much faster than C# at 4 threads but much slower as the number of threads increases. It also seems C# has become quicker per iteration, when the thread count has increased. Graphs are included in this post:

Java vs C# with a threadpool size of 4 threads Java vs C# with a threadpool size of 32 threads Peter's Java answer (see below) vs C#, for 32 threads

The Java implementation was written on a 64bit Hotspot JVM, with Java 7 and using an Executor Service threadpool I found online (see below). I also set the JVM to concurrent GC.

C# was written on .net 3.5 and the threadpool came from codeproject: http://www.codeproject.com/Articles/7933/Smart-Thread-Pool

(I have included the code below).

My questions:

1) Why is Java getting slower but C# is getting quicker?

2) Why do the execution times of C# fluctuate greatly? (This is our main question)

We did wonder whether the C# fluctuation was caused by the memory bus being maxed out....

Code (Please do not highlight errors with locking, this is irrelevant with my aims):

Java

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class PoolDemo {

    static long FastestMemory = 2000000000;
    s
Edit
Report

1 Answer

11

You don't appear to be testing the threading frame work as much as you are testing how the language optimises un-optimised code.

Java is particular good at optimising pointless code, which I believe would explain the difference in the languages. As the number of threads grows, I suspect the bottle neck moves to how the GC performs or some thing else incidental to your test.

Java could also be slowing down as its not NUMA aware by default. Try running -XX:+UseNUMA However I suggest for maximum performance you should try to keep each process to a single numa region to avoid cross numa overhead.

You can also try this slightly optimise code which was 40% fast on my machine

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class PoolDemo {

    static long FastestMemory = 2000000000;
    static long SlowestMemory = 0;
    static long TotalTime;
    static long[] FileArray;
    static FileOutputStream fout;

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

        int Iterations = Integer.parseInt(args[0]);
        int ThreadSize = Integer.parseInt(args[1]);

        FileArray = new long[Iterations];
        fout = new FileOutputStream("server_testing.csv");

        // fixed pool, unlimited queue
        ExecutorService service = Executors.newFixedThreadPool(ThreadSize);
        //ThreadPoolExecutor executor = (ThreadPoolExecutor) service;

        for (int i = 0; i < Iterations; i++) {
            Task t = new Task(i);
            service.execute(t);
        }

        service.shutdown();
        service.awaitTermination(90, TimeUnit.SECONDS);

        System.out.println("Fastest: " + FastestMemory);
        System.out.println("Average: " + TotalTime / It
answered 2012-04-05T11:55:06.427

Your Answer