469,342 Members | 6,455 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,342 developers. It's quick & easy.

benchmarks? java vs .net

The shootout site has benchmarks comparing different languages. It
includes C# Mono vs Java but not C# .NET vs Java. So I went through
all the benchmark on the site ...

http://kingrazi.blogspot.com/2008/05...enchmarks.html

Just to keep the post on topic for my friends at comp.lang.c++, how do
I play default windows sounds with C++?

Jun 27 '08
358 11407
On Thu, 05 Jun 2008 10:54:33 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>And Mersenne Twister, where F# is also 2x faster than Java.
It's empty claim since we have no chance to look at the code. The link
you gave was broken.

I wonder why Harpo doesn't post the link? Perhaps he knows the claim
will be debunked if we have a chance to optimize?
Jun 27 '08 #201
On Thu, 5 Jun 2008 06:22:50 +0100, Jon Skeet [C# MVP]
<sk***@pobox.comwrote:
>And I for one have never been claiming that .NET or C# is significantly
faster than Java overall. (If any benchmarks made custom calls to
native code, that would be interesting. I really have no idea how JNI
compares with P/Invoke in terms of speed. I know which is more pleasant
to use, mind you :)
This benchmark uses JNI to call libGMP

http://shootout.alioth.debian.org/gp...igits&lang=all

Jun 27 '08 #202
Razii wrote:
On Thu, 05 Jun 2008 10:54:33 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>>And Mersenne Twister, where F# is also 2x faster than Java.

It's empty claim since we have no chance to look at the code. The link
you gave was broken.
The link is fine:

http://www.math.sci.hiroshima-u.ac.j...JAVA/java.html
I wonder why Harpo doesn't post the link? Perhaps he knows the claim
will be debunked if we have a chance to optimize?
Try to optimize this one, for example:

http://www.math.sci.hiroshima-u.ac.j.../MTRandom.java

F# is 2x faster than this Java (and shorter, and more composable, and ...).

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #203
Barry Kelly wrote:
Jon Harrop wrote:
>Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
That is Java outperforming C#, not .NET.
No, it's Java outperforming .NET calling a virtual method. It has
nothing to do with the code that the IL is generated in: if you have a
virtual method which isn't overridden, the .NET CLR will not inline
calls to it. The Hotspot VM will inline it until it first sees the
method being overridden. The difference here is in the jitting model,
not in the language.

Try it in F#, ensuring that the method is virtual and actually called
each time (consider that the method might be one which has side-
effects). I can't see how it would possibly have a different result.

This optimization can obviously be done statically by the compiler.

No - this optimization cannot be done statically for runtimes that
support dynamic code loading, as the CLR and JVM do...
I just posted a working example where the optimization is done, so it is
clearly not impossible. The only question is (subjectively) was my code
equivalent.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #204
Razii wrote:
On Thu, 05 Jun 2008 10:58:53 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>>The fast .NET code is already on the shootout site (again).

I tested it and it's slowest.
Tested what, exactly? Where are your results? What is your setup? How did
you compile it? etc.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #205
On Thu, 05 Jun 2008 18:00:14 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>F# is 2x faster than this Java (and shorter, and more composable, and ...).
Post the link to F# and C# versions.
Jun 27 '08 #206
On Thu, 05 Jun 2008 18:11:00 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
How did you compile it? etc.
fsc binarytreesf.fs

$ time binarytreesf 20
stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1

real 1m16.180s
user 0m0.000s
sys 0m0.046s

that was slowest...

Jun 27 '08 #207
Razii wrote:
On Thu, 05 Jun 2008 10:59:58 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>>Again, the fast .NET code (and compilation instructions) are already on
the shootout site. There is nothing for me to do (except tell you the same
thing over and over).

F# was much slower than C# and slowest of all...

$ time binarytreesf 20 (F#)
...
real 1m16.180s
user 0m0.000s
sys 0m0.046s
This takes 68s here.
$ time java -server -Xms64m binarytrees 20 (Java)
...
real 0m36.328s
user 0m0.031s
sys 0m0.046s
This takes 69s here.

Given that my CPU (2.2GHz Athlon64 X2) predates yours and is roughly half as
fast on other benchmarks overall, it is clear that your result for F# is
anomalous: taking longer on a much faster machine.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #208
Razii wrote:
On Thu, 05 Jun 2008 18:11:00 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>How did you compile it? etc.

fsc binarytreesf.fs

$ time binarytreesf 20
stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1

real 1m16.180s
user 0m0.000s
sys 0m0.046s

that was slowest...
Try inserting:

[<CompilationRepresentation(CompilationRepresentati onFlags.PermitNull)>]

before the line:

type 'a tree = ...

and then try compiling with optimizations enabled:

fsc -O3 binarytrees.fs

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #209
Jon Skeet [C# MVP] wrote:
Mark Thornton <mt*******@optrak.co.ukwrote:
>>(Another nail in the coffin of the claim that ".NET is twice as slow as
Java" though,
>I don't see much in these benchmarks of the sort of code where the more
mature HotSpot JIT could be expected to outshine .NET.

As it is, Java outperforms .NET (on my box) by about 3:1.
Making GetNumber non-virtual, and .NET outperforms Java (on my box)
about about 2:1.

Pointless benchmark, of course, other than to show the inlining
capabilities of Hotspot in the face of a virtual method which hasn't
been overridden.
It does have real relevance. I have classes with multiple
implementations, but quite frequently a given process will only use one
of the possible implementations.

Mark Thornton
Jun 27 '08 #210
Razii wrote:
On Wed, 4 Jun 2008 23:07:29 +0100, Jon Skeet [C# MVP]
<sk***@pobox.comwrote:
>Oh indeed. The fact that there's both Math and StrictMath is
particularly nice. It would be interesting to see a port of StrictMath
for .NET.

Since 1.4 Math just calls StrictMath for sin and cos. That's how sin
and cos got slower since 1.4. However, there is solution to it.

http://pastebin.com/f126f0c27
That might be what appears in the library source, but it isn't what
actually happens once a call has been compiled.

Mark Thornton

Jun 27 '08 #211
Jon Harrop <jo*@ffconsultancy.comwrote:
This optimization can obviously be done statically by the compiler.
No - this optimization cannot be done statically for runtimes that
support dynamic code loading, as the CLR and JVM do...

I just posted a working example where the optimization is done, so it is
clearly not impossible. The only question is (subjectively) was my code
equivalent.
Is your method virtual, and called virtually? If not, then it's not
equivalent. If it is, then the JIT can't inline it.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #212
Mark Thornton <mt*******@optrak.co.ukwrote:
Pointless benchmark, of course, other than to show the inlining
capabilities of Hotspot in the face of a virtual method which hasn't
been overridden.

It does have real relevance. I have classes with multiple
implementations, but quite frequently a given process will only use one
of the possible implementations.
Fair enough - but it's only significant if:
a) the implementation is small enough to inline
b) the method call would be a significant hit, i.e. it's a bottleneck
in the app

Obviously I can't speak for your experience, but mine is certainly that
the two don't come together very often. More likely in the scientific
world than the business world, I suspect.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #213
Jon Harrop wrote:
Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
That is Java outperforming C#, not .NET.
No, it's Java outperforming .NET calling a virtual method. It has
nothing to do with the code that the IL is generated in: if you have a
virtual method which isn't overridden, the .NET CLR will not inline
calls to it. The Hotspot VM will inline it until it first sees the
method being overridden. The difference here is in the jitting model,
not in the language.

Try it in F#, ensuring that the method is virtual and actually called
each time (consider that the method might be one which has side-
effects). I can't see how it would possibly have a different result.

This optimization can obviously be done statically by the compiler. There is
no assurance that F# will also fail to optimize this, particularly if you
write a functional equivalent:
We're not talking about "functional equivalents". We're talking about
virtual methods that are callable by third-party code written in any CLR
language, i.e. methods for which a MethodInfo instance can be obtained
from reflection, and for which MethodInfo.IsVirtual returns true and
MethodInfo.IsFinal returns false.

Any code in F# or any other language which doesn't compile to something
that can be loaded in MethodInfo form via System.Reflection doesn't
apply, because it simply isn't a virtual method.

-- Barry

--
http://barrkel.blogspot.com/
Jun 27 '08 #214
Jon Skeet wrote:
Mark Thornton <mt*******@optrak.co.ukwrote:
Pointless benchmark, of course, other than to show the inlining
capabilities of Hotspot in the face of a virtual method which hasn't
been overridden.
It does have real relevance. I have classes with multiple
implementations, but quite frequently a given process will only use one
of the possible implementations.

Fair enough - but it's only significant if:
a) the implementation is small enough to inline
b) the method call would be a significant hit, i.e. it's a bottleneck
in the app

Obviously I can't speak for your experience, but mine is certainly that
the two don't come together very often. More likely in the scientific
world than the business world, I suspect.
FWIW, when one adopts the test-first style of development, the ability
to create mocks (whether by inheritance or the proxy capabilities of the
CLR/etc.) and use dependency injection frameworks (inversion of control
pattern) to abstract away your dependencies becomes very important.

It's then that the ability of the runtime to optimize virtual method
calls to statically dispatched calls becomes a lot more important,
because:

1) Usually, the only point of a method being virtual is so that it can
easily be mocked

2) Usually, when running "for real" and not for test, only a single
implementation of that method will be loaded into the runtime.

I wouldn't discard the utility of the virtual -static call
optimization so trivially.

Of course, some kind of more direct language or runtime support for
mocking and / or inversion of control might be a better solution than
willy-nilly making every method virtual, as that has other, more severe
repercussions for designability and testability - classes with virtual
methods being a lot harder to test due to the extra code paths.

-- Barry

--
http://barrkel.blogspot.com/
Jun 27 '08 #215
Barry Kelly <ba***********@gmail.comwrote:
Obviously I can't speak for your experience, but mine is certainly that
the two don't come together very often. More likely in the scientific
world than the business world, I suspect.

FWIW, when one adopts the test-first style of development, the ability
to create mocks (whether by inheritance or the proxy capabilities of the
CLR/etc.) and use dependency injection frameworks (inversion of control
pattern) to abstract away your dependencies becomes very important.
True.
It's then that the ability of the runtime to optimize virtual method
calls to statically dispatched calls becomes a lot more important,
because:

1) Usually, the only point of a method being virtual is so that it can
easily be mocked

2) Usually, when running "for real" and not for test, only a single
implementation of that method will be loaded into the runtime.
Absolutely. I don't dispute that at all - I just wonder how often those
virtual methods are both small enough to be inlined *and* critical for
performance.

I'm sure there are some cases where it makes a really huge difference -
but I suspect it makes a *slight* difference to a far greater
proportion of apps.
I wouldn't discard the utility of the virtual -static call
optimization so trivially.
One reason it's so important in Java of course is that methods are
virtual by default. C# (and VB.NET, I believe) methods are non-virtual
by default. The defaults wouldn't make a difference if every developer
diligently thought about whether or not to make a method virtual every
time they wrote it - but of course, few people (myself *not* included)
are that diligent.
Of course, some kind of more direct language or runtime support for
mocking and / or inversion of control might be a better solution than
willy-nilly making every method virtual, as that has other, more severe
repercussions for designability and testability - classes with virtual
methods being a lot harder to test due to the extra code paths.
Well, just because an interface has a virtual method doesn't mean it
has to be virtual in the implementing class. But yes, inheritence of
implementation certainly has a design cost associated with it.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #216
On Thu, 05 Jun 2008 18:54:02 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>Given that my CPU (2.2GHz Athlon64 X2) predates yours and is roughly half as
fast on other benchmarks overall, it is clear that your result for F# is
anomalous: taking longer on a much faster machine.
Well, here is F#

http://shootout.alioth.debian.org/gp...ng=fsharp&id=0

and java

http://shootout.alioth.debian.org/gp...ng=javaxx&id=2

anyone can test it and see if they get different result. The only
ctiteria is using java -server -Xms64m (not -Xmx64m)

F# Mono is also slower than C# Mono according to the site.
Jun 27 '08 #217
Barry Kelly wrote:
Jon Harrop wrote:
>Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
That is Java outperforming C#, not .NET.

No, it's Java outperforming .NET calling a virtual method. It has
nothing to do with the code that the IL is generated in: if you have a
virtual method which isn't overridden, the .NET CLR will not inline
calls to it. The Hotspot VM will inline it until it first sees the
method being overridden. The difference here is in the jitting model,
not in the language.

Try it in F#, ensuring that the method is virtual and actually called
each time (consider that the method might be one which has side-
effects). I can't see how it would possibly have a different result.

This optimization can obviously be done statically by the compiler. There
is no assurance that F# will also fail to optimize this, particularly if
you write a functional equivalent:

We're not talking about "functional equivalents".
I know. That is why I said you are talking about C# and not .NET.
We're talking about virtual methods
That only exist in OOP.
that are callable by third-party code
That cannot be imposed in such a way that it prohibits static optimization.
written in any CLR language,
CLR languages are not necessarily capable of producing C#-compatible virtual
methods.
i.e. methods for which a MethodInfo instance can be obtained
from reflection, and for which MethodInfo.IsVirtual returns true and
MethodInfo.IsFinal returns false.
That does not obviate static optimization.
Any code in F# or any other language which doesn't compile to something
that can be loaded in MethodInfo form via System.Reflection doesn't
apply, because it simply isn't a virtual method.
Even if I use the FFI to enforce the generation of a virtual method there is
nothing to stop the F# compiler from inlining it when that is statically
possible (as it is in this case).

I'm not disagreeing with any of your statements. I am simply saying that
they do not apply to all .NET languages. Indeed, they only make sense in
object oriented languages.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #218
Jon Skeet [C# MVP] wrote:
Mark Thornton <mt*******@optrak.co.ukwrote:
>>Pointless benchmark, of course, other than to show the inlining
capabilities of Hotspot in the face of a virtual method which hasn't
been overridden.
It does have real relevance. I have classes with multiple
implementations, but quite frequently a given process will only use one
of the possible implementations.

Fair enough - but it's only significant if:
a) the implementation is small enough to inline
b) the method call would be a significant hit, i.e. it's a bottleneck
in the app

Obviously I can't speak for your experience, but mine is certainly that
the two don't come together very often. More likely in the scientific
world than the business world, I suspect.
I do vehicle routing algorithms, so although the application is sold to
businesses, its core is more scientific/mathematical in nature. Using
100% CPU is routine. I'm working on achieving that for multi core
machines as well.

Mark Thornton
Jun 27 '08 #219
On Thu, 05 Jun 2008 19:01:42 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>[<CompilationRepresentation(CompilationRepresentati onFlags.PermitNull)>]

before the line:

type 'a tree = ...

and then try compiling with optimizations enabled:

fsc -O3 binarytrees.fs
fsc -O3 binarytreesf.fs

binarytreesf.fs(23,30): warning FS0062: This construct is for
compatibility with
OCaml. The expression form 'expr.(expr)' is for use when OCaml
compatibility is
enabled. In F# code you may use 'expr.[expr]'. A type annotation may
be require
d to indicate the first expression is an array. This warning can be
disabled usi
ng '--ml-compatibility', '--no-warn 62' or '#nowarn "62"'

binarytreesf.fs(23,16): warning FS0062: This construct is for
compatibility with
OCaml. Consider using the overloaded operator 'int' instead. This
warning can b
e disabled using '--ml-compatibility', '--no-warn 62' or '#nowarn
"62"'

$ time binarytreesf 20
stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1

real 0m58.576s
user 0m0.015s
sys 0m0.015s

not it gets same time as C#
Jun 27 '08 #220
Razii wrote:
F# Mono is also slower than C# Mono according to the site.
That does not surprise me. Mono is much less efficient than .NET at handling
the abstractions that F# uses. The SciMark2 benchmark in F# is 3x faster
on .NET than Mono, for example.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #221
Jon Harrop <jo*@ffconsultancy.comwrote:
CLR languages are not necessarily capable of producing C#-compatible virtual
methods.
At that point the situation I originally described is no longer
applicable then, is it? Here's what I wrote:

<quote>
Pointless benchmark, of course, other than to show the inlining
capabilities of Hotspot in the face of a virtual method which hasn't
been overridden.
</quote>

If the method isn't virtual (at the .NET IL level) then you're not
reproducing the situation in which Java outperforms .NET.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #222
On Thu, 05 Jun 2008 18:00:14 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>Try to optimize this one, for example:

http://www.math.sci.hiroshima-u.ac.j.../MTRandom.java

F# is 2x faster than this Java (and shorter, and more composable, and ...).
Though you have not given F# and C# version, I did test the above
class. Tell me if I did anything wrong.

public class test2
{
public static void main (String[] args)
{

MTRandom mt = new MTRandom ();
for (int i = 0;i < 100000000;i++)
{
mt.next (32);
}
}
}

$ time java -server test2
real 0m3.301s

$ time java test2
real 0m4.265s

Now here is a different version of MersenneTwister than what you
posted.

http://pastebin.com/f72f8838d

let's test this version

public class test2
{
public static void main (String[] args)
{
MersenneTwisterFast mt = new MersenneTwisterFast ();

for (int i = 0;i < 100000000;i++)
{
mt.nextInt();
}
}
}

$ time java -server test2

real 0m1.012s
user 0m0.000s
sys 0m0.031s

$ time java test2

real 0m1.966s
user 0m0.000s
sys 0m0.030s

This version is already 3.2 times faster than the link you posted.
Jun 27 '08 #223
On Thu, 05 Jun 2008 18:54:02 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>$ time java -server -Xms64m binarytrees 20 (Java)
...
real 0m36.328s
user 0m0.031s
sys 0m0.046s

This takes 69s here.
On my comp that takes 32 seconds. However, it's possible to double the
speed again by using these flags:

$ time java -server -Xms512m -Xmx512m -XX:NewRatio=1 binarytrees 20

stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1

real 0m16.955s
user 0m0.015s
sys 0m0.015s

tha's now 3.4 times faster than C# and F#. If anyone wants to test it,
(C#)
http://shootout.alioth.debian.org/gp...ng=csharp&id=0

(Java)
http://shootout.alioth.debian.org/gp...ng=javaxx&id=2

(F#)
http://shootout.alioth.debian.org/gp...ng=fsharp&id=0

Jun 27 '08 #224
Razii <nu*********@mail.comwrote:

<snip>
tha's now 3.4 times faster than C# and F#. If anyone wants to test it,
On my box, where I don't have the server JVM installed at the moment,
the .NET version *was* much slower than the Java version, until I
forced the .NET GC into server mode, which made .NET merely "a bit
slower" than Java. Create BinaryTrees.exe.config with this in it:

<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
</configuration>

Then retry. It made a big difference on my box (although I don't
entirely trust the result on my box, as the disk is thrashing atm). See
what it does on yours.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #225
On Thu, 5 Jun 2008 22:31:41 +0100, Jon Skeet [C# MVP]
<sk***@pobox.comwrote:
>On my box, where I don't have the server JVM installed at the moment,
In this case, the difference between client and server is only 3
seconds.
>until I
forced the .NET GC into server mode, which made .NET merely "a bit
slower" than Java. Create BinaryTrees.exe.config with this in it:

<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
</configuration>

Then retry.
Yes, this did make a big difference

0m25.368s (.NET with above included)
0m18.097s (client with -Xms512m -Xmx512m -XX:NewRatio=1)
0m15.218s (-server -Xms512m -Xmx512m -XX:NewRatio=1 )

Jun 27 '08 #226
On Thu, 05 Jun 2008 17:03:27 -0500, Razii <ni*******@mail.comwrote:
>>On my box, where I don't have the server JVM installed at the moment,
If you have JDK installed, you do have server. Change your path so
that Windows find java.exe in JDK directory before it finds the one in
System32 directory.

Jun 27 '08 #227
Razii <ni******@mail.comwrote:
On Thu, 05 Jun 2008 17:03:27 -0500, Razii <ni*******@mail.comwrote:
>On my box, where I don't have the server JVM installed at the moment,

If you have JDK installed, you do have server. Change your path so
that Windows find java.exe in JDK directory before it finds the one in
System32 directory.
Ah, handy.

Okay, here are my timings then - wallclock only:

Java: ~15s
..NET: ~28s

I'll try to find more GC settings - a quick look at Perfmon suggests
it's spending most of its time there. It could well be that Java's GC
is better for this test scenario.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #228
Jon Harrop wrote:
Barry Kelly wrote:
Jon Harrop wrote:
Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
That is Java outperforming C#, not .NET.

No, it's Java outperforming .NET calling a virtual method.
This optimization can obviously be done statically by the compiler. There
is no assurance that F# will also fail to optimize this, particularly if
you write a functional equivalent:
We're not talking about "functional equivalents".

I know. That is why I said you are talking about C# and not .NET.
We're talking about virtual methods

That only exist in OOP.
Like it or not, virtual methods are part of the CLR (and JVM), and if
you want your language, be it functional, procedural, logic,
object-oriented, data-flow oriented, functional-reactive,
actor-oriented, or using any other paradigm, to interact with code
written for that platform, then it needs to support at least calling
virtual methods and, for deep interaction, providing virtual methods for
others to call.

FWIW, virtual methods, in isolation, aren't so OOP-bound as you assert.
Virtual methods are functions dynamically dispatched over a single type.
They implement a limited form of runtime overload resolution. Lisp-style
(CLOS) multi-dispatch is effectively fully orthogonal runtime overload
resolution. If a functional language is to support dynamic features like
runtime code generation and code loading, it would do well to support
overload resolution at runtime too, but further generalizing it to
pattern matching, rather than just type matching.
that are callable by third-party code

That cannot be imposed in such a way that it prohibits static optimization.
written in any CLR language,

CLR languages are not necessarily capable of producing C#-compatible virtual
methods.
Sure. That's why we have definitions like CLS-producer and CLS-consumer,
as well as a distinction between correctness and verifiability.

To the extent that a language is a CLS-producer and intends to produce
verifiable code, then it is constrained not to break the virtual method
contract.

To the extent that a language is only a CLS-consumer, and only produces
correct code, then it is free to break any contracts it likes, including
non-type-safe constructs (aka unsafe code in C#). A compromise is
possible, of course, with appropriate annotations & documentation, like
C++/CLI and C# itself.

CLS-constrained code is not necessarily merely "C#-compatible"; it is
intended to be compatible with *every* language running on the CLR, to
the extent that those languages are CLS-consumers.
I'm not disagreeing with any of your statements. I am simply saying that
they do not apply to all .NET languages. Indeed, they only make sense in
object oriented languages.
No, they make sense for languages that are intended to (1) produce
verifiable code and (2) be CLS-producer languages.

Limit (2) and you limit your language's market; limit (1) and you limit
the viability of your language as an application/web server development
platform.

F# has its own syntax to produce code that can be called by other CLS
consumers, so it is a CLS-producer (I don't know to how complete a
degree). Since you can write virtual methods in F# (using the "abstract"
member specification), an equivalent test to the one Jon Skeet posted
would necessarily include using virtual methods. The whole point of the
test is to micro-benchmark single-type polymorphic dispatch.

-- Barry

--
http://barrkel.blogspot.com/
Jun 27 '08 #229
Jon Skeet wrote:
Barry Kelly <ba***********@gmail.comwrote:
2) Usually, when running "for real" and not for test, only a single
implementation of that method will be loaded into the runtime.

Absolutely. I don't dispute that at all - I just wonder how often those
virtual methods are both small enough to be inlined *and* critical for
performance.
I was more focusing on the ability of the JVM to optimize a dynamic
dispatch to a static dispatch, rather than virtual method inlining per
se.

Both can be relevant, but I think the first is more important (certainly
for Java code) than the second; but the first also has applications more
generally to IoC etc.

-- Barry

--
http://barrkel.blogspot.com/
Jun 27 '08 #230
Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
>CLR languages are not necessarily capable of producing C#-compatible
virtual methods.

At that point the situation I originally described is no longer
applicable then, is it? Here's what I wrote:

<quote>
Pointless benchmark, of course, other than to show the inlining
capabilities of Hotspot in the face of a virtual method which hasn't
been overridden.
</quote>

If the method isn't virtual (at the .NET IL level) then you're not
reproducing the situation in which Java outperforms .NET.
Exactly. And avoiding that issue does not make anything harder on .NET.

The converse is not true of Java though. For example, having to avoid tail
calls because they have never been properly implemented in the JVM makes
some things much harder.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #231
Jon Skeet [C# MVP] wrote:
Razii <nu*********@mail.comwrote:

<snip>
>tha's now 3.4 times faster than C# and F#. If anyone wants to test it,

On my box, where I don't have the server JVM installed at the moment,
the .NET version *was* much slower than the Java version, until I
forced the .NET GC into server mode, which made .NET merely "a bit
slower" than Java. Create BinaryTrees.exe.config with this in it:

<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
</configuration>

Then retry. It made a big difference on my box (although I don't
entirely trust the result on my box, as the disk is thrashing atm). See
what it does on yours.
Yes, that also more than doubled the performance.

Here is an alternative (parallelized) F# version that also more than doubles
the performance:

#light

#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5"
#r @"C:\Program Files\Microsoft Parallel Extensions Jun08
CTP\System.Threading.dll"

[<CompilationRepresentation(CompilationRepresentati onFlags.PermitNull)>]
type 'a tree = Empty | Node of 'a tree * 'a * 'a tree

let inline make0 i = Node(Empty, i, Empty)

let inline make1 i =
let t = make0 (2*i)
Node(t, i, t)

let inline make2 i =
Node(make1 (2*i - 1), i, make1 (2*i))

let rec make_aux i = function
| 2 -make2 i
| d -Node(make_aux (2*i - 1) (d-1), i, make_aux (2*i) (d-1))

let make i = function
| 0 -make0 i
| 1 -make1 i
| d -make_aux i d

let rec check = function
| Empty -0
| Node(l, i, r) -i + check l - check r

let min_depth = 4
let max_depth =
let n = try int Sys.argv.[1] with _ -20
max (min_depth + 2) n
let stretch_depth = max_depth + 1

let loop_depth d () =
let niter = 1 <<< (max_depth - d + min_depth)
let mutable c = 0
for i = 1 to niter do
c <- c + check(make i d) + check(make (-i) d)
niter, d, c

let main() =
let c = check (make 0 stretch_depth)
Printf.printf "stretch tree of depth %i\t check: %i\n" stretch_depth c
let long_lived_tree = make 0 max_depth
let futures =
[ for d in min_depth .. 2 .. max_depth ->
System.Threading.Tasks.Future.Create(loop_depth d) ]
for future in futures do
let niter, d, c = future.Value
printf "%i\t trees of depth %i\t check: %i\n" (2 * niter) d c
Printf.printf "long lived tree of depth %i\t check: %i\n"
max_depth (check long_lived_tree)

do
let t = new System.Diagnostics.Stopwatch()
t.Start()
main()
printf "%d\n" t.ElapsedMilliseconds

This is now 2x faster than Java again but the benchmark is flawed so we can
keep doing this forever.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #232
On Fri, 06 Jun 2008 01:54:46 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>This is now 2x faster than Java again but the benchmark is flawed so we can
keep doing this forever.
It's not. Your version is exactly same speed as C# (in fact slightly
slower): 0m28.575s. (I was getting 25.38 with C#).

Skeet also got same numbers as me, basically .NET is 1.6 to 2 two
times slower.
Jun 27 '08 #233
Barry Kelly wrote:
Jon Harrop wrote:
>Barry Kelly wrote:
We're talking about virtual methods

That only exist in OOP.

Like it or not, virtual methods are part of the CLR (and JVM), and if
you want your language, be it functional, procedural, logic,
object-oriented, data-flow oriented, functional-reactive,
actor-oriented, or using any other paradigm, to interact with code
written for that platform, then it needs to support at least calling
virtual methods...
What is the difference between the IL for a call to a virtual method and the
IL for a call to a non-virtual method?
FWIW, virtual methods, in isolation, aren't so OOP-bound as you assert.
You can't cite a language that provides virtual methods without being an OOP
language because having virtual methods makes it an OOP language.
Virtual methods are functions dynamically dispatched over a single type.
They implement a limited form of runtime overload resolution. Lisp-style
(CLOS) multi-dispatch is effectively fully orthogonal runtime overload
resolution. If a functional language is to support dynamic features like
runtime code generation and code loading, it would do well to support
overload resolution at runtime too, but further generalizing it to
pattern matching, rather than just type matching.
There are many other forms of dispatch but that does not mean that virtual
methods transcend OOP.
written in any CLR language,

CLR languages are not necessarily capable of producing C#-compatible
virtual methods.

Sure. That's why we have definitions like CLS-producer and CLS-consumer,
as well as a distinction between correctness and verifiability.

To the extent that a language is a CLS-producer and intends to produce
verifiable code, then it is constrained not to break the virtual method
contract.

To the extent that a language is only a CLS-consumer, and only produces
correct code, then it is free to break any contracts it likes, including
non-type-safe constructs (aka unsafe code in C#). A compromise is
possible, of course, with appropriate annotations & documentation, like
C++/CLI and C# itself.

CLS-constrained code is not necessarily merely "C#-compatible"; it is
intended to be compatible with *every* language running on the CLR, to
the extent that those languages are CLS-consumers.
The distinction is academic (see below).
>I'm not disagreeing with any of your statements. I am simply saying that
they do not apply to all .NET languages. Indeed, they only make sense in
object oriented languages.

No, they make sense for languages that are intended to (1) produce
verifiable code and (2) be CLS-producer languages.
My statement was equivalent to (2) because your notion of "CLS-producer"
requires OOP.
Limit (2) and you limit your language's market; limit (1) and you limit
the viability of your language as an application/web server development
platform.

F# has its own syntax to produce code that can be called by other CLS
consumers,
What do you mean by "has its own syntax"?
so it is a CLS-producer (I don't know to how complete a degree).
Again, that is an academic distinction. It is useless in practice.

For example, the RedGate ANTS profiler for C# breaks when it encounters ILX.
So if I sell you a ".NET library" that happens to be written in F# it can
break your existing tools and libraries. That could be commercial suicide
so nobody takes that risk.

That means that, in practice, I cannot sell libraries written in F# to
general .NET programmers. So instead of using F# as a "CLS-producer" we
write our own compilers that generate C# source code and we sell that
instead. Our advertising even states "100% managed C#" because it gives
customers a warm fuzzy feeling and they are more likely to buy.

So I recommend forgetting about this utopian idea of CLS-producers and look
simply at what products are shipping today. Incidentally, you said that
such issues would limit a language's market but our products for F# users
sell 10x more than our products for C# users.
Since you can write virtual methods in F# (using the "abstract"
member specification), an equivalent test to the one Jon Skeet posted
would necessarily include using virtual methods.
For some subjective notion of equivalence, yes.
The whole point of the test is to micro-benchmark single-type polymorphic
dispatch.
Ironically, that does not satisfy your implied notion of equivalence because
it is not specific to virtual methods and OOP.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #234
Razii wrote:
On Thu, 05 Jun 2008 18:54:02 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>>$ time java -server -Xms64m binarytrees 20 (Java)
...
real 0m36.328s
user 0m0.031s
sys 0m0.046s

This takes 69s here.

On my comp that takes 32 seconds. However, it's possible to double the
speed again by using these flags:

$ time java -server -Xms512m -Xmx512m -XX:NewRatio=1 binarytrees 20

stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1

real 0m16.955s
user 0m0.015s
sys 0m0.015s

that's now 3.4 times faster than C# and F#.
As I said before, this benchmark is completely flawed and we can carry on
optimizing forever.

Here is another F# implementation that is much faster than your Java
(again):

#light

#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5"
#r @"C:\Program Files\Microsoft Parallel Extensions Jun08
CTP\System.Threading.dll"

[<CompilationRepresentation(CompilationRepresentati onFlags.PermitNull)>]
type 'a tree = Empty | Node of 'a tree * 'a * 'a tree

let inline make0 i = Node(Empty, i, Empty)

let inline make1 i =
let t = make0 (2*i)
Node(t, i, t)

let inline make2 i =
Node(make1 (2*i - 1), i, make1 (2*i))

let rec make_aux i = function
| 2 -make2 i
| d -Node(make_aux (2*i - 1) (d-1), i, make_aux (2*i) (d-1))

let make i = function
| 0 -make0 i
| 1 -make1 i
| d -make_aux i d

let rec check = function
| Empty -0
| Node(l, i, r) -i + check l - check r

let min_depth = 4
let max_depth =
let n = try int Sys.argv.[1] with _ -20
max (min_depth + 2) n
let stretch_depth = max_depth + 1

let loop_depth d () =
let niter = 1 <<< (max_depth - d + min_depth)
let mutable c = 0
for i = 1 to niter do
c <- c + check(make i d) + check(make (-i) d)
niter, d, c

let main() =
let c = check (make 0 stretch_depth)
Printf.printf "stretch tree of depth %i\t check: %i\n" stretch_depth c
let long_lived_tree = make 0 max_depth
let futures =
[ for d in min_depth .. 2 .. max_depth ->
System.Threading.Tasks.Future.Create(loop_depth d) ]
for future in futures do
let niter, d, c = future.Value
printf "%i\t trees of depth %i\t check: %i\n" (2 * niter) d c
Printf.printf "long lived tree of depth %i\t check: %i\n"
max_depth (check long_lived_tree)

do
let t = new System.Diagnostics.Stopwatch()
t.Start()
main()
printf "%d\n" t.ElapsedMilliseconds

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #235
Razii wrote:
On Fri, 06 Jun 2008 01:54:46 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>>This is now 2x faster than Java again but the benchmark is flawed so we
can keep doing this forever.

It's not. Your version is exactly same speed as C# (in fact slightly
slower): 0m28.575s. (I was getting 25.38 with C#).

Skeet also got same numbers as me, basically .NET is 1.6 to 2 two
times slower.
You are obviously not using the optimized code that I just posted.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #236
Jon Skeet [C# MVP] wrote:
Razii <ni******@mail.comwrote:
>On Thu, 05 Jun 2008 17:03:27 -0500, Razii <ni*******@mail.comwrote:
>>On my box, where I don't have the server JVM installed at the moment,

If you have JDK installed, you do have server. Change your path so
that Windows find java.exe in JDK directory before it finds the one in
System32 directory.

Ah, handy.

Okay, here are my timings then - wallclock only:

Java: ~15s
.NET: ~28s

I'll try to find more GC settings - a quick look at Perfmon suggests
it's spending most of its time there. It could well be that Java's GC
is better for this test scenario.
The command line options that Razii chose effectively turn off the GC.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #237
On Fri, 06 Jun 2008 02:35:44 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>Here is another F# implementation that is much faster than your Java
(again):
It's not. It's slower. Obviously we don't get the same results. Let a
third person test it. Perhaps Skeet has F#.

Jun 27 '08 #238
Razii wrote:
Now here is a different version of MersenneTwister than what you
posted.

http://pastebin.com/f72f8838d
...
$ time java -server test2

real 0m1.012s
user 0m0.000s
sys 0m0.031s

$ time java test2

real 0m1.966s
user 0m0.000s
sys 0m0.030s

This version is already 3.2 times faster than the link you posted.
For 10^9 ints I get:

Java: 13.5s
F#: 16.7s

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #239
On Fri, 06 Jun 2008 02:55:49 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>For 10^9 ints I get:

Java: 13.5s
F#: 16.7s
Ok, then this MersenneTwister is no longer twice slower.

Can you post the C# and F# versions (add the exact method that tests
it). You can use pastebin.com
Jun 27 '08 #240
On Fri, 06 Jun 2008 02:46:48 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>
The command line options that Razii chose effectively turn off the GC.
They don't.

$ time java -server -verbose:gc -Xms512m -Xmx512m -XX:NewRatio=1
binarytrees 20

stretch tree of depth 21 check: -1
[GC 196608K->49364K(491520K), 0.1513998 secs]
[GC 245972K->49372K(491520K), 0.0885678 secs]
[GC 245980K->49384K(491520K), 0.0668613 secs]
[GC 245992K->49384K(491520K), 0.0972670 secs]
[GC 245992K->49384K(491520K), 0.0669637 secs]
[GC 245992K->49392K(461696K), 0.0675055 secs]
[GC 216176K->49520K(428992K), 0.1238719 secs]
[GC 216304K->49520K(464000K), 0.0010244 secs]
[GC 197488K->49520K(410176K), 0.0008281 secs]
2097152 trees of depth 4 check: -2097152
[GC 197488K->49536K(464384K), 0.0008021 secs]
[GC 193024K->49520K(464960K), 0.0012254 secs]
[GC 193008K->49504K(465728K), 0.0015697 secs]
[GC 193888K->49520K(465088K), 0.0009092 secs]
[GC 193904K->49536K(468416K), 0.0008899 secs]
[GC 198400K->49536K(466880K), 0.0008026 secs]
[GC 198400K->49520K(472128K), 0.0010054 secs]
[GC 205360K->49520K(470144K), 0.0009445 secs]
[GC 205360K->49520K(476480K), 0.0009811 secs]
[GC 213808K->49520K(474240K), 0.0008553 secs]
524288 trees of depth 6 check: -524288
[GC 213808K->49536K(481024K), 0.0008600 secs]
[GC 222848K->49520K(478720K), 0.0009234 secs]
[GC 222832K->49520K(485568K), 0.0008998 secs]
[GC 231984K->49520K(483328K), 0.0008445 secs]
[GC 231984K->49520K(489984K), 0.0008858 secs]
[GC 240880K->49504K(487808K), 0.0008590 secs]
[GC 240864K->49536K(494080K), 0.0008913 secs]
[GC 249216K->49504K(492032K), 0.0012131 secs]
131072 trees of depth 8 check: -131072
[GC 249184K->49536K(497856K), 0.0009522 secs]
[GC 256960K->49536K(496000K), 0.0008328 secs]
[GC 256960K->49536K(501312K), 0.0009298 secs]
[GC 264064K->49520K(499648K), 0.0008124 secs]
[GC 264048K->49536K(504384K), 0.0008989 secs]
[GC 270400K->49536K(502912K), 0.0008489 secs]
[GC 270400K->49536K(507136K), 0.0009511 secs]
[GC 276032K->49520K(505792K), 0.0020848 secs]
32768 trees of depth 10 check: -32768
[GC 276016K->49584K(509568K), 0.0009982 secs]
[GC 281072K->49520K(508352K), 0.0010441 secs]
[GC 281008K->49680K(511680K), 0.0011986 secs]
[GC 285584K->49632K(510656K), 0.0011478 secs]
[GC 285536K->49600K(513536K), 0.0011361 secs]
[GC 289344K->49584K(512640K), 0.0009221 secs]
8192 trees of depth 12 check: -8192
[GC 289328K->50128K(515200K), 0.0019249 secs]
[GC 293264K->49808K(514368K), 0.0013610 secs]
[GC 292944K->50256K(516672K), 0.0026040 secs]
[GC 296464K->49936K(515968K), 0.0018862 secs]
[GC 296144K->49632K(517824K), 0.0009684 secs]
[GC 298336K->50272K(517312K), 0.0023415 secs]
[GC 298976K->50160K(518848K), 0.0020201 secs]
2048 trees of depth 14 check: -2048
[GC 300912K->51296K(518336K), 0.0043586 secs]
[GC 302048K->50160K(519360K), 0.0021542 secs]
[GC 302000K->50096K(518912K), 0.0018978 secs]
[GC 301936K->50032K(520064K), 0.0017406 secs]
[GC 303408K->51504K(519744K), 0.0049608 secs]
[GC 304880K->49920K(520192K), 0.0015220 secs]
512 trees of depth 16 check: -512
[GC 303616K->57844K(519936K), 0.0258907 secs]
[GC 311540K->57748K(514816K), 0.0083801 secs]
[GC 306068K->60308K(517056K), 0.0134347 secs]
[GC 308628K->62864K(511296K), 0.0258077 secs]
[GC 304784K->60912K(509376K), 0.0125694 secs]
[GC 302832K->57056K(514432K), 0.0036414 secs]
128 trees of depth 18 check: -128
[GC 299104K->77972K(514048K), 0.0723174 secs]
[GC 320020K->86728K(494080K), 0.0540681 secs]
[GC 308424K->120252K(504064K), 0.1391573 secs]
[GC 341948K->119644K(476544K), 0.0396110 secs]
[GC 313820K->117212K(490304K), 0.0492557 secs]
[GC 311388K->114764K(491392K), 0.0430719 secs]
[GC 310028K->113420K(490304K), 0.0325961 secs]
[GC 308684K->112092K(494912K), 0.0283435 secs]
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1

real 0m15.210s
user 0m0.000s
sys 0m0.015s

Jun 27 '08 #241
Jon Harrop <jo*@ffconsultancy.comwrote:
I'll try to find more GC settings - a quick look at Perfmon suggests
it's spending most of its time there. It could well be that Java's GC
is better for this test scenario.

The command line options that Razii chose effectively turn off the GC.
No they don't. They allocate a fixed sized heap (512M), one with a an
equal size of old/new spaces, but one which is still garbage collected.

The test creates a total of 305135616 instances of TreeNode. Without
garbage collection, each node couldn't even take 2 bytes without
running out of memory.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #242
On Jun 6, 12:48 am, Barry Kelly <barry.j.ke...@gmail.comwrote:
Jon Skeet wrote:
Barry Kelly <barry.j.ke...@gmail.comwrote:
2) Usually, when running "for real" and not for test, only a single
implementation of that method will be loaded into the runtime.
Absolutely. I don't dispute that at all - I just wonder how often those
virtual methods are both small enough to be inlined *and* critical for
performance.

I was more focusing on the ability of the JVM to optimize a dynamic
dispatch to a static dispatch, rather than virtual method inlining per
se.
Good point. I'd been completely ignoring the cost of the vtable
lookup.
Both can be relevant, but I think the first is more important (certainly
for Java code) than the second; but the first also has applications more
generally to IoC etc.
Right. It would be very interesting to get stats (for various
applications - it's no doubt *highly* sensitive to what application
you're running) on:
1) What proportion of method calls are theoretically virtual in Java
2) What proportion of method calls are *actually* executed virtually
in Java
3) What proportion of method calls are virtual in .NET

Jon
Jun 27 '08 #243
On May 31, 6:28 am, King Raz <klgfgfgj...@mail.comwrote:
The shootout site has benchmarks comparing different languages. It
includes C# Mono vs Java but not C# .NET vs Java. So I went through
all the benchmark on the site ...

http://kingrazi.blogspot.com/2008/05...java-benchmark...

Just to keep the post on topic for my friends at comp.lang.c++, how do
I play default windows sounds with C++?
C++ standards don't mention any 'sound' concept. Try trolling some
platform specific groups!
Jun 27 '08 #244
Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
I'll try to find more GC settings - a quick look at Perfmon suggests
it's spending most of its time there. It could well be that Java's GC
is better for this test scenario.

The command line options that Razii chose effectively turn off the GC.

No they don't. They allocate a fixed sized heap (512M), one with a an
equal size of old/new spaces, but one which is still garbage collected.
The number of garbage collections plummets.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #245
On Fri, 6 Jun 2008 04:04:38 -0700 (PDT), asterisc <Ra*******@ni.com>
wrote:
>C++ standards don't mention any 'sound' concept. Try trolling some
platform specific groups!
He is the only one who fell into the trap and responded :)

How do I use GCC on Windows?

Let's if he responds again.

Jun 27 '08 #246
On Fri, 06 Jun 2008 13:44:50 +0100, Jon Harrop <jo*@ffconsultancy.com>
wrote:
>The number of garbage collections plummets.
Yes, there are less garbage collections calls (that was the tweak
obviously) but all garbage is collected.
Jun 27 '08 #247
Razii wrote:
How do I use GCC on Windows?
Similar to other platforms.

Arne
Jun 27 '08 #248
On Jun 6, 1:44*pm, Jon Harrop <j...@ffconsultancy.comwrote:
Jon Skeet [C# MVP] wrote:
Jon Harrop <j...@ffconsultancy.comwrote:
The command line options that Razii chose effectively turn off the GC.
Interesting.. After N 1000 "man years" of development of our garbage
collector, how do we use to best advantage?

Turn the f**g thing off!

:-)

regards
Andy Little


Jun 27 '08 #249
Jon Skeet [C# MVP] wrote:
Jon Harrop <jo*@ffconsultancy.comwrote:
>Here, let me help:

$ time java -server -verbose:gc -Xms3g -Xmx3g -XX:NewRatio=1 binarytrees
16
stretch tree of depth 17 check: -1
131072 trees of depth 4 check: -131072
32768 trees of depth 6 check: -32768
8192 trees of depth 8 check: -8192
2048 trees of depth 10 check: -2048
512 trees of depth 12 check: -512
128 trees of depth 14 check: -128
32 trees of depth 16 check: -32
long lived tree of depth 16 check: -1

real 0m2.964s
user 0m1.472s
sys 0m1.356s

Now there are zero garbage collections.

Right - with those parameters, which aren't the ones Razii posted.
Razii set it at half a gig, not 3 gigs.
That's not *at all* the same thing as saying that the GC has been
turned off.

Right, the GC isn't "off" in theory it just never gets called in
practice.

Except it did with the settings Razii actually posted, as opposed to
the ones you posted above.
The cost of the GC has been radically reduced,

By not running the GC we have now completely eliminated its "cost", yes.

With your changed settings, yes.
but it is still collecting garbage.

Right, the garbage all gets collected when the program terminates.

With your changes, yes.

It's really not fair to Razii to claim that he disabled the garbage
collector when his settings certainly *didn't* prevent the garbage
collector from collecting.

Please go by what he posted, not some other settings you've come up
with. Your claim that Razii "effectively turn[ed] off the GC" is simply
untrue.
My claim was clearly perfectly correct.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #250

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.