0

are there any benchmarks available for comparing memory access to off heap memory in Java Unsafe vs. Java vs. C regions? For example the Java LZ4 (or L4Z?) compression library stated that their Java port using Unsafe is 66% of the speed of the native C implementation.

Q: Is there anything that can give me a (better) estimate?

I wonder if it is worth to go for a C solution of a certain library if one has Unsafe and what parts should I port. Using off-heap memory or heap memory with large arrays (megabytes) might not be such a big saver. The only thing worth mentioning is that using unsafe I can use what ever granularity I want by reading integers at any offset instead of bytes and so on. This would greatly improve the algorithm for one problem I try to speed up.

Martin Kersten
  • 5,127
  • 8
  • 46
  • 77

1 Answers1

1

Yes. The only thing that can give you a better estimation is a trial, similar to what the author ran, but on the systems and using the programs you intend to use rather than the systems and programs the author intends to use to test.

I would assume the author who "stated that their Java port using Unsafe is 66% of the speed of the native C implementation" has the intention of selling his product using any means possible.

Consider that there is no "native C implementation", currently, nor will there likely ever be because C was designed to be portable. The only thing "native" is machine code, and even that invokes some debate on occasions. There are good C compilers and bad C compilers. Both qualities form "native" machine code. Which one was used in the test?

Once you translate C or Java to machine code or JVM bytecode, it's no longer C or Java. It's machine code or JVM bytecode. This brings me to my next point, which I'll phrase in the form of a question: If a program in C and a program in Java which perform the same task, are both compiled to the same JVM bytecode, which program is faster?

We can't measure speed until we have attribution of speed to instructions, cache misses and all of that. While their code might have been "66% of the speed of the native C implementation" (whatever that means anyway), they could have performed some very skewed optimisations, tailored to their own machine, to obtain those figures.

In summary, the tests the author has performed are only realistic if you intend to run those tests on the authors computer, which isn't necessarily your own software on your own computer.

autistic
  • 1
  • 3
  • 35
  • 80
  • You are correct. I wanted also to add the author compiled all the c source along with the c++ using his CPU as target platform giving gcc the chance to do the normal optimization one can expect. So I think he gave it the best try possible. And yes you are right. I do not go for absolute but relative figures. Maybe there is a memory access heavy algorithm or benchmark run in that regard. – Martin Kersten Apr 04 '15 at 16:12
  • gcc can either be a well-optimised compiler (when `-O3` is used) or a poorly-optimised compiler (when `-O0` is used). In any case, I'm actually biased towards C because the entire rationale behind undefined behaviour is optimisation. There's no bounds checking requirement in C because it could impose extra runtime requirements. Not to mention the garbage collection in Java. GC'd code can be optimal, but not Java's GC'd code. Even when using Java Unsafe, there's still a garbage collector attempting to reclaim objects in the background all by it's lonesome rather than using hints from developer. – autistic Apr 05 '15 at 01:35
  • It's a myth that C doesn't have a garbage collector. C doesn't require a garbage collector, but there's the possibility for `malloc` to allocate by proxy of a GC and `free` to provide hints to a GC. Similarly, C doesn't require bounds checking, yet clang does have the [address sanitizer](http://clang.llvm.org/docs/AddressSanitizer.html) which performs bounds checking among other things (at a cost). It seems to me as though any optimisation that the Java compiler performs can be performed by C compilers, but it doesn't seem like Java compilers can perform all optimisations that C compilers can. – autistic Apr 05 '15 at 01:40
  • Well sure that are all valid questions. The GC stuff in the background is a non issue since I am interested in speeding up a certain portion of the code. This portion is a realtime decompression of strings using a certain static encoding/decoding scheme. So the question is about memory access with lays the actual foundation. Since Java for instance does not allow one to read integers from byte stream without accessing each byte independently Unsafe does. Moving all the computation in a C routine would even more speed things up. – Martin Kersten Apr 05 '15 at 01:56
  • And sure as the ultimate fighting skill one can use Assembler to optimize the C stuff by hand. One thing I truly miss in Java is embedding Assembler directly into the Java Code and execute the correct version of it based on the underlying platform. That is missing for so long. – Martin Kersten Apr 05 '15 at 01:57
  • There's also [LLJVM](http://da.vidr.cc/projects/lljvm/), which can produce JVM bytecode from LLVM bytecode. That's probably an even better option, because it seems F.O.S.S. and there are many more languages that translate to LLVM than just C. For example, Rust might be an option? – autistic Apr 05 '15 at 02:04