jextract looses type safety in generated bindings

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Apr 7 13:43:08 UTC 2021


On 07/04/2021 11:57, Maurizio Cimadamore wrote:
> If the latter, we had an API similar to that in an earlier iteration 
> of the Panama project (another Pointer-like API); while this API was 
> enough, from an expressiveness perspective, to support jextract use 
> cases, it also added noticeable overhead to basic operation like 
> pointer dereference. 

To give a better ideas of the numbers involved - there is a nice native 
interop shootout here:

https://github.com/zakgof/java-native-benchmark

This was ran against the old Panama API, the one featuring the 
high-level Pointer API. As you can see Panama doesn't come out too well 
in that benchmark.

For fun, I've ported the benchmark using the API we have released in 
Java 16, and here are the results I have:

```
Benchmark                                   Mode  Cnt Score     Error  Units
JmhCallOnly.bridj                           avgt   50   279.563 ▒   
4.312  ns/op
JmhCallOnly.jna                             avgt   50   826.049 ▒ 
11.840  ns/op
JmhCallOnly.jna_direct                      avgt   50   934.675 ▒ 
13.662  ns/op
JmhCallOnly.jni_javacpp                     avgt   50    36.899 ▒   
0.618  ns/op
JmhCallOnly.jnr                             avgt   50   233.757 ▒   
3.090  ns/op
JmhCallOnly.panama                          avgt   50    30.332 ▒   
0.386  ns/op
JmhGetSystemTimeSeconds.bridj               avgt   50  1306.806 ▒ 
131.925  ns/op
JmhGetSystemTimeSeconds.java_calendar       avgt   50   136.437 ▒   
3.949  ns/op
JmhGetSystemTimeSeconds.java_date           avgt   50    50.450 ▒   
0.750  ns/op
JmhGetSystemTimeSeconds.java_localdatetime  avgt   50    58.232 ▒   
1.456  ns/op
JmhGetSystemTimeSeconds.jna                 avgt   50  3194.622 ▒ 
216.633  ns/op
JmhGetSystemTimeSeconds.jnaDirect           avgt   50  3227.971 ▒ 
193.953  ns/op
JmhGetSystemTimeSeconds.jni_javacpp         avgt   50   418.683 ▒   
5.789  ns/op
JmhGetSystemTimeSeconds.jnr                 avgt   50   327.486 ▒   
7.548  ns/op
JmhGetSystemTimeSeconds.panama              avgt   50   390.615 ▒   
3.987  ns/op
```

(all this has been ran unscientifically, using a VirtualBox instance :-) )


As you can see, the API we have in 16 are pretty competitive with JNI - 
only JNR does better, but I believe that's due to differences in how 
memory is allocated - e.g. the memory segment API does a malloc and a 
free, and it also zeroes memory (as well as keeping track of how much 
memory has been allocated in the JDK as a whole, which is a need for 
us). I'm pretty sure that (a) JNR doesn't bother with any of this 
(rightfully so!) and (b) if we started playing with custom segment 
allocators (which the latest API allows you to do) we can obtain numbers 
which surpass everything seen here (as we can amortize the allocation cost).

When it comes to overhead for a single native call (e.g. ignoring memory 
allocation overhead), you can see that the Linker API in 16 comes out 
the best of the bunch.

So, every interop solution in this space picks a different compromise 
when it comes to expressiveness vs. performance. You can see how our 
APIs have benefited by going lower level - we started off being the 
slowest and ended up there with the best (there is some 10x gain in 
there). Of course users are free to pick the solution they prefer, 
depending on the particular use cases they are facing.

Maurizio




More information about the panama-dev mailing list