
Differences Between the CLR and the JVM - networked
http://cobra-language.com/trac/cobra/wiki/DifferencesBetweenClrAndJvm
======
pavanky
This is not "differences between CLR and JVM", but more of "why I think CLR is
better than JVM".

Anyway the biggest issue I have seen in my line of work (building GPU
software, and people want GPU acceleration from their language of choice) is
that JVM does not provide a way to handle external resources properly. Calling
garbage collection does not guarantee that the out of scope objects will be
finalized. This results in either code that uses up a lot of memory or code
that is very un-java like.

Yes I know try with resources exist, but the problem still exists for any
temporary variables you create within the block.

If anyone here has a better solution, I am all ears.

~~~
sk5t
I suggest never to call the garbage collector with the expectation that
anything in particular will happen--not in CLR and not in the JVM. Also, do
not use finalizers for this!

JNI and P/Invoke are not really that different except that P/Invoke is a lot
easier to implement. But CLR does not know how to cleanup unmanaged resources
automagically.

edit: I removed my notes about "try with resource" and AutoCloseable

~~~
pavanky
Well the only solution remaining is writing C like code, where users have to
allocate and free memory manually which is not a solution if you ask me.

~~~
kinghajj
May I interest you in Rust? [https://www.rust-lang.org/](https://www.rust-
lang.org/)

~~~
pavanky
We already have a wrapper for rust[1] and C++, fortran, python and various
other languages[2].

I was talking about people not wanting to move away from _their_ language of
choice which results in us having to try and support them as well.

[1] [https://github.com/arrayfire/arrayfire-
rust](https://github.com/arrayfire/arrayfire-rust)

[2] [https://github.com/arrayfire](https://github.com/arrayfire)

------
sk5t
This is a weird collection of observations about C# and CLR intermingled
without apparent rhyme or reason, although the author seems to understand that
they are not interchangeable...

~~~
newobj
sk5t as in sk5t@cmu.edu?

~~~
sk5t
Yep. Do we know each other?

------
recursive
> C# has partial classes > C# can have multiple classes in a single file

Perhaps there are others, but these have nothing to do with the CLR. A JVM
language could easily have these features if the language supported it.

~~~
draw_down
Right, that's why it says "C# has", not "CLR has".

~~~
bmay
It says both - those "C# has" bullets are under a "CLR has…" header.

~~~
RubyPinch
> It also bleeds into differences between C# and Java whose features often
> include compiler-level-only features that the underlying VirtualMachine is
> not cognizant of.

aka "if the list says C#, its because it applies to C# and not CLR"

------
noblethrasher
Comparing the CLR and JVMs in terms of anything other than features is
bizarre.

This is because the CLR/VES and JVMs are both examples of the actual important
thing about general purpose computing: _Computers can simulate anything,
including “better” computers_ (that’s what Universal Turing Machine means).

But, when using one computer to simulate a “better” one, you’re always going
to be giving up some raw performance that you don’t care about in order to get
some features that you desperately want (after all, you are going through the
enormous trouble of designing/implementing/running a simulation of another
freaking general purpose computer).

Now, “better” can mean lots of things:

• The simulated computer has unbounded memory

• The simulated computer doesn’t (under|over)flow on arithmetic

• There are more people on the market that know how to program the simulated
computer

• The simulated computer is more widely deployed

• The simulated computer is more secure/reliable

• The simulated computer is not controlled by a single faction

• The simulated computer readily runs programs encoded in your favorite
language

• The simulated computer can easily simulate a computer that runs programs
encoded in your favorite language ( _the subject of the article_ )

So, simulated computer A is strictly better than simulated computer B only in
the following cases:

• A has the features that you want and B does not

• A and B both have the features that you want, but the former traded away
_significantly_ less raw performance than did the latter.

Since the CLR and JVMs are so similar with respect to performance, you should
only compare them in terms of the features that you want. Personally, I think
that MS was wise to go for more features at the expense of some performance
since that’s really the whole point of a VM. But, unfortunately for them (and
fans of CLR/VES/C#/VB/F#) they (historically) could not compete on features
that quite a few people really care about (e.g. not perceived to be controlled
by a single company, runs well on Linux, marketable in the Valley, etc.)

------
groovy2shoes
CLR also supports proper tail calls, where the JVM does not (yet).

~~~
jdmichal
Though it's important to note that it's only a _suggestion_ for the CLR
runtime. For instance, in .NET v2 (which as an engine also covers v3) it was
rare for tail call optimization to trigger in 64-bit mode. They finally fixed
this in .NET v4 to make F# viable.

[https://blogs.msdn.microsoft.com/clrcodegeneration/2009/05/1...](https://blogs.msdn.microsoft.com/clrcodegeneration/2009/05/11/tail-
call-improvements-in-net-framework-4/)

~~~
MichaelGG
Though note F# avoids .tail and turns recursive calls into loops when able.

~~~
jdmichal
I think it's the .NET JIT that turns the self-recursive calls into loops. But
yes, this is all covered in the link I included.

~~~
MichaelGG
Well since .tail is only a hint, F# must do it in some cases. Try writing a
simple recursive function in tail call style and look at the IL produced by
fsc.

~~~
jdmichal
I was basing my statement on this line from the MSDN blog I linked:

> This is such an important concept that the JIT has a special path just for
> turning functions that call themselves in a tail recursive manner into
> loops.

However, it looks like (in at least some cases) that fsc unrolls the recursion
prior to the JIT:

    
    
        let rec fact n acc =
            match n with
            | 0 -> acc
            | _ -> fact (n-1) (acc*n)
    
        .method assembly static int32  fact@1(int32 n,
                                              int32 acc) cil managed
        {
          // Code size       24 (0x18)
          .maxstack  5
          IL_0000:  ldarg.0
          IL_0001:  switch     ( 
                                IL_0016)
          IL_000a:  ldarg.0
          IL_000b:  ldc.i4.1
          IL_000c:  sub
          IL_000d:  ldarg.1
          IL_000e:  ldarg.0
          IL_000f:  mul
          IL_0010:  starg.s    acc
          IL_0012:  starg.s    n
          IL_0014:  br.s       IL_0000
          IL_0016:  ldarg.1
          IL_0017:  ret
        } // end of method TailTest::fact@1

------
jcranmer
JVM doesn't really have a notion of virtual versus non-virtual methods, it's a
matter of which calling opcode you use (invokevirtual versus invokespecial).

It's also sort of missing the big difference... the JVM is generally superior
in performance to the CLR, having a better JIT and better GC performance.

~~~
bunderbunder
I'm not sure I'd consider performance a big difference. Their performance is
generally very close, and if you're in a situation to care enough about
performance to split hairs then you really shouldn't be using a managed
platform in the first place.

The _real_ big difference is that Java has an enormous open source ecosystem,
whereas much of what .NET has is ports or clones of successful Java projects.

That said, I think .NET's probably the better choice for a lot of line-of-
business applications simply because the tooling allows for very rapid
development of that sort of stuff, and not having easy access to Hadoop or
Akka really isn't much of a handicap when you're mostly just banging out a
mess of business rules.

~~~
jcranmer
The title implies that it's comparing the runtime engines, and the performance
is absolutely a major selling point of any such comparison, even if the
practical effect of any difference is negligible. Ultimately, the comparison
claims to be between the CLR and the JVM while it's more like between C# and
Java, given how it only covers fairly superficial features at the front-end
level and not what can and can't be done in VM code, let alone how different
VM architectures can have major impacts on code design, etc.

~~~
bunderbunder
I think the reason for this particular list is that it's from the standpoint
of a programming language implementation team, and one that's currently
working on targeting a 2nd platform.

Given that, it reads as a list of what the VM can do for you and what you'll
need to do yourself in the compiler.

------
13of40
Splitting hairs, but the CLR is just one implementation of the Virtual
Execution System (VES). The spec for all of this behavior is about the VES.

------
derefr
Having recently been tinkering with the Objective-C Runtime (writing a bridge
to another language), I think it'd be interesting to extend the comparison
there as well. Actually, a more systemic review of what all the various
various _runtime platforms_ are capable of, apart from any particular
languages implemented on those platforms, would be excellent reading.

(For just one example, I'd really like to see a comparison of the
availability+overhead of various concurrency primitives in the runtimes of the
JVM vs. Erlang's BEAM, vs. Obj-C's libdispatch, etc. The _languages_ on each
platform emphasize concurrency differently, but often at the VM level things
are more similar than people think.)

------
astral303
Isn't the JVM's notion of packages and class loaders effectively the same
thing as CLR namespaces?

~~~
sk5t
The most analogous thing to a JVM classloader in CLR is the AppDomain.

Java packages and .NET namespaces are largely similar (the CLR supports a
superset of naming concepts like explicit implementation).

------
ryanlm
In the end it seems like CLR is superior to the JVM based on these assertions.

~~~
Mikeb85
Except for the fact the JVM has far superior performance...

~~~
sremani
I understand JVM is battle tested on Linux, *BSD, where CLR would have to
catch up, but are there any technical reasons say JVM perfs better than CLR on
windows.

~~~
Mikeb85
> but are there any technical reasons say JVM perfs better than CLR on windows

Considering the amount of man-hours that have gone into both, the exact
reasons are probably hidden under a whole bunch of implementation details.

That being said, I've run benchmarks where the JVM (version 1.8) outperforms
C++ and Fortran... The JVM seemingly optimizes everything, and the amount of
fine tuning you can do is amazing.

I've never heard of the CLR coming close to Java performance on large-ish apps
or tasks, all else being equal.

~~~
iconhacker
Why every Java app is so slow and memory hungry?!!

~~~
Mikeb85
There's plenty of slow, memory hungry C++ apps too. Just enterprise software
things...

~~~
iconhacker
Plenty != every. And comparing IntelliJ and Visual studio 201*, there is no
chance Java is winning.

~~~
sievebrain
There are fast, optimised Java apps as well. IntelliJ is actually a good
example - on my laptop it starts in a few seconds, the UI is snappy and
responsive, it looks native. Back when I used Eclipse I thought the same as
you; Java apps must just inherently suck. The difference in performance
between IntelliJ and Eclipse put that idea to bed for good.

The real reason Java apps are often associated with being big and heavy is
less to do with the technology and more to do with the fact that it's so often
used for bespoke enterprise apps where there's no competition and so little
incentive to optimise (vs add new features).

~~~
iconhacker
I agree that IntelliJ is OK comparing with other Java apps. It is never near
performant. Visual Studio being 32 bit app is still much faster than 64 bit
IntelliJ, given that IntelliJ can use much more memory. Every time, people
complain about IntelliJ, they are told that they will need better hardware.
The reason Enterprises chose Java, is because they don't care about
performance that much.

~~~
sievebrain
Visual Studio being 32 bit is an embarrassment for Microsoft in this day and
age. That's exactly the kind of technical hole that JetBrains avoided when
they bet on Java to write their IDEs in. The transition for them from 32 bit
to 64 bit was extremely smooth despite having a huge plugin ecosystem. I've
read about the bizarre hacks people with big Visual Studio projects have to
use to ensure they can actually load them, that's just not sustainable.

I haven't compared the speed of a recent VS vs IntelliJ as I use a Mac now
(another benefit JB got from going with Java). But of my complaints about
IntelliJ none are really related to speed.

BTW if it's typing responsiveness you're thinking of, I recall that JB had
some inefficient drawing algorithms which they've optimised in very recent
builds (or it might even be an experimental feature still). It could cause
issues on slow graphics cards. That isn't a Java issue though, it was just IJ
using inefficient graphics code.

~~~
iconhacker
I have used latest edition of IntelliJ on OsX. IntelliJ is acceptable but not
smooth at all considering that I have 16g ram with 1tb Ssd. And font rendering
due to the jvm swing bug is hurting eyes. It is far fetched to say the
experience is any pleasant. To fix the issue of Java, jetbrain bundles their
custom built jdk

~~~
sievebrain
I use IntelliJ on the same setup and don't see any font issues. I haven't
noticed any lack of smoothness either, but perhaps we have different standards
for that.

~~~
iconhacker
Another important performance issue is related to Java's handling about
generic type erasure and auto boxing. This is one of the biggest design issue
comparing with C#'s handling. So manipulating bytes is a pain. And there is
even no unsigned byte. Benchmark does not represent real world use case. I
don't feel Java is much faster than Python or Ruby. But there is too much
boilerplate code comparing with C#. The pure Java language is clean. But with
Spring framework and various Apache common, endless different logging
framework, it makes the language such a hassle to deal with. Just my 2 cents.

------
known
What's the size of a typical CLR and JVM?

------
nicobn
There's nothing stopping you from declaring additional static classes inside a
class in Java. You can definitely declare multiple classes in a single file.

~~~
jdmichal
That's not even close to the same thing. C# allows declaration of types within
other types, but it also allows declaration of multiple top-level types within
a single compilation unit. And with partial classes, it also allows
declaration of a single type across multiple compilation units.

~~~
nicobn
The point that was made is that multiple (static) classes cannot be declared
in the same file, which is 100% false. I'm not arguing that C# is functionally
equivalent to Java. There was no mention of "compilation unit" or "partial
classes", which are a completely different subject.

It doesn't matter whether the additional classes defined in the file are top
level or not, they're still classes that can be used independently.

~~~
jdmichal
You are being disingenuous. "File" is layman-speak for "compilation unit", so
it is not a "completely different subject". You cannot declare multiple top-
level types in a single compilation unit in Java. Yes, you can create static
types within another type. However, those are not top-level types; they are
scoped within the type they are declared in.

Let's just put it this way. Would a Java programmer, by way of normal
operation, implement a project with a few Java files, each of which contains a
type with several static types internal to it, and where those internal static
types are in fact the main types of the program? If they wouldn't, then there
is no equivalency, because this _is_ something you see in C# code bases _all
the time_.

