Saturday, July 26, 2008

Benchmarking the CLR vrs the JVM

I've found that there are lots of flame wars regarding JVM/CLR performance, but very little solid data, so I thought I'd try running a benchmark of my own.

I decided the first benchmark would be sorting using a bubble sort. The bubble sort is highly inefficient, so it is a good demonstration of memory management and integer arithmetic.

I also wanted to see how well the JIT's would handle method by method optimization, so I wrote a version that used methods for each runtime, as well as a version that was entirely inline.

My theory was that the inline version would prove to be slower than the method invoking versions due to JIT optimizations when calling methods. In reality, it was even more apparent. However, when I did disable the JIT optimizations on the CLR by using a debug build, the inline CLR version was much faster than the method version.



This data was generated on my 2.4ghz laptop running Windows XP. I used the .NET 2.0 CLR, and JRE 1.6.0.5 (Which just happened to be the one that came with Eclipse). The Y axis is milliseconds.

The benchmark is performing a bubblesort on a 10,000 integer set, 100 times.

It shows that the CLR is a slight winner, at least in doing these operations. The big surprise was the speed difference the JVM JIT makes when optimizing methods.

Even the unoptimized CLR version was only slightly slower than the JVM.

The surprising lesson learned here is that premature optimization by inlining methods and unrolling loops may actually result in slower performance on the JVM.

If anyone wants to run these benchmarks on their machine, the full source is here.

16 comments:

jherber said...

I don't know how much difference it would make, but you unfairly penalizing the Java code. You are creating Date() objects in loops (at least 300), while the C# code is merely calling a property on DateTime.

An equal benchmark would require you remove the extra object creation for the java code, replacing the "new Date().getTime()" call with "System.currentTimeMillis()".

See here for further if you are unfamiliar with the Java way:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#currentTimeMillis()

Jonathan Holland said...

jherber: Thats a good point, so I reran the java code using System.currenTimeMillis();

It did not make a noticeable difference whatsoever. Any time saved is too small to be measured in millis.

If you don't believe me, you've got the code, try it yourself.

Anonymous said...

I am curious how Mono compares since, as the cross-platform CLR, it is more equivalent to the JVM than the MS .NET stack.

Tonetheman said...

I run Ubuntu 8.04 and here are the results from mono. I cut them off after a while.

agcc@agcc-laptop:~/projects/benchmark2$ mono Bubblesort.exe
511.017
505.38
504.2
504.384
504.122
504.037
504.491
504.703
503.593
503.536
504.593
503.743
503.725
503.58
504.213
543.752
503.536
503.532
503.862

I am not sure if you wanted some thing else run. The Benchmark.java file runs considerably faster on my machine.
agcc@agcc-laptop:~/projects/benchmark2$ java Benchmark
407
378
376
377
377
377
377
377
377
377
417

Here is the mono version I used.
agcc@agcc-laptop:~/projects/benchmark2$ mono --version
Mono JIT compiler version 1.2.6 (tarball)
Copyright (C) 2002-2007 Novell, Inc and Contributors. www.mono-project.com
TLS: __thread
GC: Included Boehm (with typed GC)
SIGSEGV: altstack
Notifications: epoll
Architecture: x86
Disabled: none

and here is the gmcs (c#) compiler versionagcc@agcc-laptop:~/projects/benchmark2$ gmcs --version
Mono C# compiler version 1.2.6.0

Jonathan Holland said...

tonetheman: Your Java scores a good bit slower than the ones I got.

However, it appears that Mono's CLR implementation is not nearly as fast as either the JVM, or the MS CLR.

Thanks for running those.

Anonymous said...

Did you try to run that Java code with the -server switch? In XP the JVM defaults to -client and in Linux to -server. There is a small performance difference: http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=java&lang2=javaclient

Anonymous said...

Hi Jonathan

You are benchmarking the java client VM. It offeres similar performance to the CLR usually.

To test the server VM (the optimised Java version) you need to use the -server switch. e.g. java -server Benchmark.

I ran your tests on my system. Using Benchmark.java as supplied I get a time of around 94 milliseconds using -server. This is more than twice as fast as the client JVM on my system. I would be very surprised of the CLR could beat it.

You should also test the IBM and JRockit (BEA) implementions of the JVM.

Kango said...

These are my results:
183
176
69
70
68
69
69
69
69
68
68
68
68
69
69
69
69
69
71
70
69
71
69
74
73
73
74
uname -a: Linux wb288 2.6.24-19-generic #1 SMP Wed Jun 18 14:15:37 UTC 2008 x86_64 GNU/Linux

Cpus x2: (cat /proc/cpuinfo)
processor : 3
vendor_id : AuthenticAMD
cpu family : 15
model : 65
model name : Dual-Core AMD Opteron(tm) Processor 2218
stepping : 3
cpu MHz : 2599.999
cache size : 1024 KB
physical id : 1
siblings : 2
core id : 1
cpu cores : 2

Is this good?

Anonymous said...

I tested the -server JVM on my system vs the CLR.

.NET CLR (using VS2008):
140 milliseconds

Java -server:
94 milliseconds

Java -client:
204 milliseconds

I haven't tested the IBM JVM and JRockit, but with the correct switches these are often even faster! I have yet to see a benchmark where .NET CLR can beat the -server JVM.

Interesting to note for JDK 7 is that tiered compilation will provide the best of both worlds for all Java apps.

Anonymous said...

Interesting to note the way you have coded it the benchmark will be testing the OSR (on stack replacement) compilation of each VM which is not optimal. The Bubblesort.Start method never pops off the stack.

Kango said...

Ran it inline as well and the numbers were about the same.

Java:
java version "1.5.0_15"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_15-b04)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_15-b04, mixed mode)

Anonymous said...

Ran on different VMs on my laptop. It stabilized around:

Sun 1.6.0_06 - 140
IBM 6.0 SR1 - 125
JRockit 1.6.0_05 - 94

Sun JVM runs with -server, no flags on the other JVMs.

Anonymous said...

I think both runtime enviroment to fullfil the required purpose. But your code is not performing a bubble sort. Just try it with an array like this:
int[] data = {5,4,3,1,2}

Anonymous said...

av女優
av情人趣味用品愛爾蘭情人趣味愛蜜莉情人趣味用品情趣用品

情趣用品情趣用品aio交友愛情館一葉情貼圖片區一葉晴貼影片區

Anonymous said...

av女優
av情人趣味用品愛爾蘭情人趣味愛蜜莉情人趣味用品情趣用品

情趣用品情趣用品aio交友愛情館一葉情貼圖片區一葉晴貼影片區

eda said...

潤滑液,SM,內衣,性感內衣,自慰器,充氣娃娃,AV,
情趣,G點,性感丁字褲,情趣,角色扮演服,吊帶襪,丁字褲,情趣用品,無線跳蛋,男女,


情趣按摩棒,自慰套,角色扮演,按摩棒,跳蛋,情趣跳蛋,
.,
按摩棒,電動按摩棒,飛機杯,視訊,自慰套,自慰套,情趣用品,情趣內衣,