Around April 2020 I started to work on Direct-BT to support high performance and parallel Bluetooth handling for medical devices (Thank you Xerxes @ Zafena),
see its history.
After the initial attempt to hack our way to success with the previous existing solution TinyB failed,
the project was launched and succeeded.
This time I chose using C++ as the fat implementation and dropping a thin Java layer on top.
- Analysis with valgrind, clang-tidy etc is well possible on the native portion but impossible with a JVM involved
- After proving the native C++ part to be correct, the thin Java layer is safe using a proven C++/JNI mapping
- Reduced not so deterministic runtime behavior due to reduced Java processing
- Allow user to chose between
- A steady set native build (C++)
- Virtual runtime w/ CPU and OS abstraction environment (Java)
- Down to the metal with a C++ 1:1 mapping from bits & bytes to high-level abstraction is just sexy!
- Using high level abstractions natively memory mapped to bytes, e.g. vector API upon float arrays.
- Direct control of atomics and locks, i.e. cache behavior and parallel
- Better performance and less memory/resource consumption (see below) means
- Faster execution/completion
- Less energy usage and costs
- Longer battery lifespan
- Downside: Losing runtime optimization like for virtual function tables (but compare to GraalVM?)
- The Computer Language 22.05 Benchmarks Game, C++ vs Java - Well written C++17/20 performs mostly 5 - 8 times faster, depending on the problem.
- C++ may only consume 1/2 - 1/30th of memory
The above is mostly of interest if you are coming from the embedded devices space
where every byte, millisecond and wattage counts.
But even on fat hosts, it won't hurt to save a dime and having more peace of mind overall.
Besides performance, in the embedded and security critical space (automotive, medical, ..)
one also focuses on deterministic reproducible code and naturally dislikes any runtime morphing magic.
However, even here Java JVMs have their place given certain constraints.
Of course, Java's managed code APIs are very useful for a speed-up development cycle
and without debating every member field access and method call :)
It is simply cheaper in development costs to roll out your application using Java.
Hence the above hybrid path has been chosen,
leaning to the C++ native side on the provided new functionality.
Notable, the C++/JNI binding was done manually, only having a few functions and callbacks.
Most of the base functionality has been encapsulated into jaulib.
These patterns experienced could be used to create a binding generator for C++/Java.
Indeed, sometimes a truly PIA, however, one ends up with an efficient and proven solution.
Now if I would take the beans and auto-magical glue kits, non-array non-native Java field layout copied into native space or perhaps memory locked NIO, costly at creation and forbidding a fast on-the-fly utilization ..
one surely might end up with a solution in a shorter time span than described above, whether it is more efficient, natural and correct is another discussion.
Let's put a little smile on this convo, I love both world ;-)