Some late C++/Java Project Experience

Lately we started to discuss JogAmp‘s Project Management a little bit and touched things like efficient Java JNI binding to native foreign functions.

Allow me to elaborate on this issue a little bit (forum copy),  perhaps even go this far to debate down on the metal C++ vs virtual Java performance.

Keep in mind, I am an old dog and always focus on performance and such thing even on the Java side 😉

***

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 due to:

  • Validation
    • 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
  • Efficiency
    • 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?)
  • Performance

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.

***

Later I created another little project named Cipherpack utilizing the same strategy as described. Of course, to truly abstract away all odds and to gain full native functionality mapped to Java, I had to plunge into the janitor space of

Indeed, 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 😉

+++

We are open for contracting, looking for new projects.

~Sven