The Oracle JVM turned out to the be clear winner in this speed test.
See the full details here:
http://www.savagehomeautomation.com/projects/raspberry-pi-java-gpio-frequency-benchmarks.html


wiringPiSetup()hinkmond wrote:One issue to point out (as you noted) is that the Pi4J library uses JNI to access the WiringPi native C library which incurs intrinsic JNI overhead when converting from Java Strings to Native C function calls as is done in JNI, that in turn slows down the Java GPIO benchmark measurement.
Hi Hinkmond,hinkmond wrote: ...
Another approach that may avoid this JNI overhead, is by using Java to directly access the Raspian Linux file handle drivers to the GPIO interface using the RPi /sys/classes/gpio/* and Java File I/O. ...


savageautomate wrote:
Using java.nio with the Oracle JDK SE 8 (ARM preview) I am getting about 2.6kHz.
(click here to see full size image)
So now I am left thinking ... what did I do wrong?
Here are the test programs I am using that are adapted from your code. Can you take a look and see if there is something wrong in my approach?
java.io test program @ http://pastebin.com/1upsTXev
java.nio test program @ http://pastebin.com/PWjx1PKD
Unless maybe accessing GPIO via the driver interface really slows it down more than the overhead of JNI?
Thanks, Robert
String fn = "/sys/class/gpio/gpio" + GpioChannel + "/value";
RandomAccessFile memoryMappedFile = new RandomAccessFile(fn, "rw");
//Mapping a file into memory
MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 8);
// Loop forever
while (true) {
//Writing into Memory Mapped File
out.put((byte) '1');
out.put((byte) '0');
}
trouch wrote:thanks for precisions. I also choose to include native code in webiopi to get a full GPIO access through registers
I recently made some bench with java too, and I'm considering porting webiopi server to java.
But there is a big difference between 150KHz and 7Mhz !
How is compiled the native part ?
I'd like to see a native loop called from java to understand why.
savageautomate wrote:I bet if you invoke a native loop from Java you will see the same frequency results as my pure native test while the loop is running. You just have the pay for the initial overhead of Java and JNI to invoke the loop. Probably negligible.
If there any real need in your project for super hi-speed frequency on GPIO pins?
trouch wrote:Thanks for your post and blog article, it's a great complement to http://codeandlife.com/2012/07/03/bench ... pio-speed/
java.io.IOException: No matching device found
at sun.nio.ch.FileChannelImpl.map0(Native Method)
at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:835)
memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 8); long now = 0;
long then = 1;
long onesies = 2;
int loop = 1000000;
setFuction( 16, PIN_OUTPUT);
for(int rep = 0; rep <10; rep++){
then = System.nanoTime();
for(int i = 0; i<loop; i++){
jpioOut(16, 1);
jpioOut(16, 0);
};
now = System.nanoTime();
onesies = now - then;
then = System.nanoTime();
for(int i = 0; i<loop; i++){
jpioOut(16, 1);
jpioOut(16, 0);
jpioOut(16, 1);
jpioOut(16, 0);
};
now = System.nanoTime();
System.out.println("time:"+((now - then - onesies)/loop)+"ns / flash");
};JNIEXPORT void JNICALL Java_JPIO_jpioOut
(JNIEnv *env, jobject mama, jint pin, jint data)
{
if(data){
*(jpio + 7) = 1 << pin;
} else {
*(jpio +10) = 1 << pin;
};
} //jpioOutputjava.vm.vendor;Oracle Corporation
java.vm.version;1.8.0-ea
time:226ns / flash
time:349ns / flash
time:362ns / flash
time:365ns / flash
time:361ns / flash
time:384ns / flash
time:352ns / flash
time:364ns / flash
time:388ns / flash
time:348ns / flash
String filename = "/sys/class/gpio/gpio24/value";
// NOTE: Changing to a test text file works fine
// String filename = "/tmp/test.txt";
System.out.println("DEBUG: filename = "+filename);
RandomAccessFile memoryMappedFile = new
RandomAccessFile(filename, "rw");
memoryMappedFile.seek(0);
// Map the GPIO file handle into memory
FileChannel fileChannel = memoryMappedFile.getChannel();
// ERROR occurs here: No device found
MappedByteBuffer out = fileChannel.map(
FileChannel.MapMode.PRIVATE, 0, fileChannel.size());
hinkmond wrote:Hi Sebastian,
Let me take a look and figure out the right Java code to use with NIO. I recently obtained an oscilloscope for the RPi here! So, I can now reproduce the benchmark.
I'll post when I have more info...
Thanks,
Hinkmond