Differences Between the CLR and the JVM
cobra-language.com
cobra-language.com
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.
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
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.
There are actually three implementations of C on top of Graal/Truffle by now.
TruffleC was the first and it maps malloc to the JVM's Unsafe malloc equivalent. So if you double free you trash the VM basically.
ManagedC ignores calls to free() and garbage collects the C programs heap.
Sulong interprets LLVM bytecode. I don't know how it does memory management.
try (ObjectPool pool = new ObjectPool()) {
...
Foo foo = pool.register(new Foo());
...
Bar bar = pool.register(new Bar());
}
When ObjectPool is closed, it closes all its registered objects too.Note that this would be a lot easier with a language like Scala or Kotlin.
Array C = Array.Add(A, Array.sin(B))
The output C and the output of Array.sin(B) have not been allocated from the object pool.``` ArrBuilder = arrs; arrs.add(A, arrs.sin(B)); Array C = arrs.get(); ```
Otherwise if you're willing to do Lombok style AST manipulation you could of course do most anything you wanted, perhaps even proper operator overloading:
``` @Arrays public void test() { Array C = A + sin(B); } ```
(Just be ready for the Java programmers to rebel on you and your "dark arts" ;) )
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.
aka "if the list says C#, its because it applies to C# and not CLR"
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.)
To me, it seems like a list put together in a non-systematic way.
[1] https://medium.com/binary-dreams/from-java-to-scala-tail-rec...
Is rather have the JVM's compressed pointers and escape analysis.
https://blogs.msdn.microsoft.com/clrcodegeneration/2009/05/1...
> 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@1It'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.
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.
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.
Though the CLR has a lot more "outs", where you can use raw pointers and such. Even put " managed" objects on an unmanaged heap. Don't think this is possible in the JVM. So you can write more C-like code in .net then you can represent in the JVM.
And I don't know if it is possible yet, but for Java 9 Graal is an extension onto of the JVM and can run unmanaged C code alongside normal code, so it should be possible.
(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.)
Java packages and .NET namespaces are largely similar (the CLR supports a superset of naming concepts like explicit implementation).
Isn't this statement pretty much the entirety of the reason to implement multi-tiered JITs? Do a fast JIT with few optimizations to get out of interpreted mode. Then do a slow JIT after you've collected enough statistics to make good optimization decisions.
If your work has an "inner-loop" situation, then the JVM can optimize the heck out of it using statistics specific to this particular execution. That's huge.. it opens up all kinds of concrete optimizations that aren't possible with static analysis alone (precomputing call targets, knowing what to inline, etc.). I'd wager this is a major factor in cases when the JVM occasionally outperforms C.
But no, it doesn't necessarily help.
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.
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).
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.
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.
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.