Compared to other database access methods, JDBC is quite slow from LibreOffice.
As far as I understand, this is mainly because calling Java from C++ is expensive, unless there is already Java in the call stack.
"outermost" calls into JNI (i.e., not recursively from a thread that
is already in a JNI call, where jvmaccess::VirtualMachine::attachThread
would be cheap) are always expensive (and the changes to the JVM that we
tried to address with bb59742bcf4883af5876a2ffadcc4a689e414b60 only made
them extra-extra expensive, when they already had been expensive).
So, to address the JDBC slowness, we either have to reduce the number of calls to Java, or "artificially" put Java in the stack.
First idea (hackish, but could be "one fell swoop" if it works):
If we know that we are about to make a truckload of Java
calls from C++, wrap it in a Java trampoline that just calls the C++
function that will make many Java calls? So that we are in the
"recursive" case? Hmm... that could be hackish, since it would involve
generic code looking at whether it is connecting to the database
engine through JDBC (Java) or some other way.
Also, I doubt one can pass Java an arbitrary C++ function pointer to call;
one probably needs a Java class that is linked to a particular C++ function
But maybe if we put this trampoline "high enough" in the call stack, then
we don't need too many of these trampolines. I mean, for example if the
whole Base application can just trampoline Java into itself when connecting
to a JDBC data source, we need only one trampoline :)
Then the whole LibO Base (including UI) code would run with Java in
its stack, so any request it serves would 'automatically' have
Java in its stack.
Reimplement the parts of LibreOffice that do a lot of SDBC calls
in Java (as 1 SDBC call = 1 JDBC call).
Keep two parallel implementations (one C++, one Java).
Use the Java implementation for JDBC, the C++ implementation for
all other drivers.
The "keep two parallel implementations of the same code" part sucks
Change the JDBC<->SDBC driver to do aggressive caching in C++ world,
and devise an ad-hoc "transmit one full row (or even multiple rows)
in _one_ JNI call" protocol between LibO's Java part and LibO's C++
Extend SDBC to have this "fetch a whole row / multiple rows
in one API call". Implement that API call in Java for the
Use a generic C++ implementation for all other drivers.
Then stack on aggressive caching (that would use this new API call)
on top of the JDBC<->SDBC driver.
Fifth idea (Michael Meeks):
Could we have a Java thread polling a loopback socket and sucking simple
commands & parsing & executing them, then passing the data back in some
other form ;-> It'd be hideous if that actually was quicker than a
direct JNI call but ... ;-) it's possible. Particularly in the world of
under-utilized multi-threaded CPUs it might not be -so- bad.
Bit of a pain cross-platform, but might work for suitably chunky
methods; I wonder - could we use the wonder binary-urp magic to
prototype it [ though I guess we'd need a native Java implementation of
that - hmm ].
Moving enhancement -> NEW
Adding self to CC if not already on