top of page

Using Protocol Buffers with JNI

The first version of the Runtime Library for Java was based on a JNI interface with a C/C++ native library that handled PHP library function calls (like "date" or "PDO::fetchAll") directly to an embedded PHP runtime. Each time a function is called from this space, the Java arguments and return values were converted to/from PHP internal "zvals". Performance tests showed that this was about 20x slower for a basic function call.

The biggest overhead, by far, was not the creation of new values, but the interaction with Java from native code. Each time an instance type was checked, or a new object created, there was an "expensive" interaction with the Java Native API. There was always a sense that we could have done better with a binary interface, but writing a secure binary interface is no small task.

Enter the Google Protobuf library.

Google Protobuf is a highly optimized system for encoding and decoding binary data, It is extremely well tested and uses code generation to create native objects that are easy to work with. So we decided to give it a test.

The results were a 4x improvement over the previous method for a simple "min" function call test. One million iterations took 22 seconds before the changes, and 5.5 seconds using the protocol buffers. By contrast, the same test written in PHP takes 1.1 seconds, and written in native Java takes 0.002 seconds (the actual 1 million Math.min test took less than 0.001 seconds, and so we extended the test to print a sum of the Math.min results to be sure).

With a 5x difference between PHP for a simple function call overhead, rather than 20x, the runtime converter becomes much more useful as a tool for improving performance. If the PHP internal function does any non-trivial computations, that 0.0000044 second per call overhead becomes insignificant.

It is doubtful that the Runtime Converter will ever run "faster" than PHP, but by getting it pretty close, there is an opportunity to "make the switch" and look for improvements elsewhere by replacing PHP function calls and dynamic comparison operators with native Java. We already have a small library of replacement functions to cover places where the PHP runtime bridge won't work (or won't work well), such as with array functions and http server functions.

Note that improving performance or using less resources shouldn't be the only reason for converting code to Java, even though if you are serving millions of requests it could be very significant. On a large project, PHP's dynamic typing is a nightmare for development. Even type hints aren't good enough - variable typing and method calls checks are just as important - and PHP's design can't support such features. Just a simple refactor of a method signature to change its name or add a new required variable is impossible to do with PHP. Just a.simple "is this method or function used" check is impossible to do with PHP. Just knowing what method or interface a method call refers to is often impossible with PHP. With Java, a good IDE will do all these things, and so if we can convert PHP to Java and run it with similar speed and accuracy, there will be good reason to convert many projects to Java.

Featured Posts
Recent Posts
Archive
Search By Tags
Follow Us
  • Facebook Basic Square
  • Twitter Basic Square
  • Google+ Basic Square
bottom of page