

How to get C like performance in Java - codelion
http://blog.jelastic.com/2012/08/24/how-to-get-c-like-performance-in-java/

======
ajross
Always a good link to throw in in a discussion about "XXX vs. C" performance:
[http://marc.info/?l=git&m=124111702609723&w=2](http://marc.info/?l=git&m=124111702609723&w=2)

Basically it's a quick case study (in the form of a mailing list reply) of
implementing git in Java, tuning heavily for performance, and comparing to the
equally tuned C implementation. Java does well, but fundamental issues like
lack of value types (i.e. all objects must go into independently managed heap
cells) and memory typesafety (converting a SHA-1 between int[5] and byte[20]
is a bounds-checked copy in Java, where it's zero-cost in C) put a firm cap on
how fast it can be made to go.

------
burnhype
But using all these tricks just throws away reason you've moved to Java.
Following this further, you can write faster code in C when using only ASM
insets.

The next thing - almost every example of C vs. Java speed comparisons was
created by weak C programmers. The code was poor and not optimized.

------
alberich
It would be nice to see some benchmarks showing "C like" performance using
this tricks.

~~~
bunderbunder
There's an old series of back-and-forth blog posts by Rico Mariani and Raymond
Chen that shows a story along these lines for C++ vs C#. It's not C vs Java,
but it's a fairly comparable comparison since the languages have similar run-
time characteristics.

What makes it particularly interesting is that while the program in question
is small, it's much more "real-world" than what you see in most language
shootout benchmarks. And successive iterations of both the C# and C++ versions
are documented, so you can get a feel for performance in terms of both CPU
time and developer time.

The other thing that makes it particularly interesting is that the C++ version
was trailing behind the C# from the beginning when it was slower by an order
of magnitude up until it finally nosed ahead of the C# version following its
6th iteration. The C# version, by contrast, only went through two - a first
cut which the C++ one didn't even match until its 5th version, and a single
round of optimization.

Even then it's somewhat debatable that C++ won out. The final thing that let
the C++ version win was the lag the CLR needed to bootstrap itself and JIT the
code; actual time spent processing was the same. Meaning that for the purposes
of someone who's thinking about performance for programs will be running for
longer than 0.1s it's debatable whether the C++ version really won in the end
after all.

A good entry point to the series is here:
<http://blogs.msdn.com/b/ricom/archive/2005/05/19/420158.aspx>

Of course that's not to say that the opposite is true and managed languages
are fundamentally superior. There are cases where a managed language will
always be slower. (e.g., Code that frequently accesses arrays in a way that
prevents the JIT compiler from optimizing away bounds checks. And startup
time, of course.) And a program written in a managed language should always be
a memory hog compared to a (well-written, non-leaky) program written in an
unmanaged language. But I am inclined to say that the idea that languages like
C and C++ are inescapably faster than languages like Java and C# is more an
article of faith than anything else.

~~~
alberich
I don't have a reference now, but I recall reading a paper discussing this
myth de C/C++ will always be faster then higher level languages like, say,
OCaml. If I'm not mistaken, the article presented a scenario where C would be
beaten easily because the compiler couldn't safely optimize some parts of the
program (due to the use of pointers and manual memory allocation it was not
possible to tell what parts of memory was being used where, or something like
that), while the OCaml's compiler could.

It is always a matter of using the right tool for the job, after all.

~~~
bunderbunder
Memory allocation is one spot where C# and other languages that use
generational garbage collection very well. Since the heap stays compacted
there's no need to spend time hunting around for a sufficiently-sized chunk of
free memory. You just throw the new object right on top of the heap.

The same characteristic also tends to automatically produce pretty good
locality of reference without any special intervention on the part of the
programmer.

On modern computers the impact of both of these can be significant. For
example, in the series I linked above, the thing that motivated the
optimization that let Chen finally produce something faster than the C#
version was the observation that his program was spending _60% of its CPU
time_ on the 'new' operator. And the cornerstone of the optimization was
taking a cue from the way that C# handles memory allocation and implementing a
sort of low-fi mimic of generational garbage collection.

