B4Alpha-Aft3r0mega / javacpp

Automatically exported from code.google.com/p/javacpp
GNU General Public License v2.0
0 stars 0 forks source link

No <Type>Pointer.put(<Type>[] array). #11

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
It would be great if there was a method in the pointer classes for directly 
putting an array into memory. This would get rid of some of the "jni overhead" 
from each separate put(pos, value) call that otherwise is needed.

I know it's possible to put in an array via a buffer, however, for some reason, 
the performance of using JavaCPP Pointer classes is several times higher than 
that of the standard Buffer classes (at least under Android 2.3.x), so I tend 
to use <Type>Pointer in my code instead of Buffers.

Original issue reported on code.google.com by adam.waldenberg@gmail.com on 29 Feb 2012 at 9:50

GoogleCodeExporter commented 8 years ago
It's probably faster to create a Pointer object than a Buffer object, but 
Buffer should have (much) better get()/put() performance. The problem with a 
Pointer.put(array) method is that, in JNI, we either need to enter a critical 
section or work on a copy of the data, so I doubt it would be faster than 
Buffer.put(array), which was created to fix exactly that issue, among others...

Can you elaborate a bit more on your use case? Maybe I can think of a good way 
to do it within the constraints

Original comment by samuel.a...@gmail.com on 29 Feb 2012 at 11:17

GoogleCodeExporter commented 8 years ago
Actually, put(i, v) in JavaCPP is ~2-3 times faster than the same call with 
Buffers. I haven't bencmarked get() though.. The tests I did were under 
Android. And when it comes to Buffer.put(array) in Android, it's really, really 
slow, especially for floats.

Let me do a new batch of benchmarks (with source code) again... I'll post them 
here later.

Original comment by adam.waldenberg@gmail.com on 29 Feb 2012 at 12:40

GoogleCodeExporter commented 8 years ago
I made a simple little benchmark:

import android.os.Bundle;
import android.util.Log;
import com.googlecode.javacpp.FloatPointer;
import com.googlecode.javacpp.IntPointer;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

public class BasicTestActivity extends Activity {
    long lastTime;
    private long timeSinceLastCall() {
        final long timeToReturn = System.currentTimeMillis() - lastTime;
        lastTime = System.currentTimeMillis();
        return timeToReturn;
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.i("javacpp test", "Test #1: FloatBuffer.put(i, v)");
        final FloatBuffer floatBuffer = ByteBuffer.allocateDirect(3000000 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        Log.i("javacpp test", String.format("capacity(): %d", floatBuffer.capacity()));
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            for (int j = 0; j < floatBuffer.capacity(); j++) {
                floatBuffer.put(j, j);
            }
        }
        Log.i("javacpp test", String.format("Test #1 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #1.1: FloatBuffer.put(array)");
        final float[] floatArray = new float[3000000];
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            floatBuffer.put(floatArray);
            floatBuffer.position(0);
        }
        Log.i("javacpp test", String.format("Test #1.1 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #2: FloatPointer.put(i, v)");
        final FloatPointer floatPointer = new FloatPointer(3000000);
        Log.i("javacpp test", String.format("capacity(): %d", floatPointer.capacity()));
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            for (int j = 0; j < floatPointer.capacity(); j++) {
                floatPointer.put(j, j);
            }
        }
        Log.i("javacpp test", String.format("Test #2 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #3: IntBuffer.put(i, v)");
        final IntBuffer intBuffer = ByteBuffer.allocateDirect(3000000 * 4).order(ByteOrder.nativeOrder()).asIntBuffer();
        Log.i("javacpp test", String.format("capacity(): %d", intBuffer.capacity()));
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            for (int j = 0; j < intBuffer.capacity(); j++) {
                intBuffer.put(j, j);
            }
        }
        Log.i("javacpp test", String.format("Test #3 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #4: IntPointer.put(i, v)");
        final IntPointer intPointer = new IntPointer(3000000);
        Log.i("javacpp test", String.format("capacity(): %d", intPointer.capacity()));
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            for (int j = 0; j < intPointer.capacity(); j++) {
                intPointer.put(j, j);
            }
        }
        Log.i("javacpp test", String.format("Test #4 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #5: IntBuffer.get(i)");
        Log.i("javacpp test", String.format("capacity(): %d", intBuffer.capacity()));
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            for (int j = 0; j < intBuffer.capacity(); j++) {
                intBuffer.get(j);
            }
        }
        Log.i("javacpp test", String.format("Test #5 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #6: IntPointer.get(i)");
        Log.i("javacpp test", String.format("capacity(): %d", intPointer.capacity()));
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            for (int j = 0; j < intPointer.capacity(); j++) {
                intPointer.get(j);
            }
        }
        Log.i("javacpp test", String.format("Test #6 took %f seconds.", timeSinceLastCall() / 1000f));

    }
}

And here are the results:

02-29 17:25:39.965: I/javacpp test(25543): Test #1: FloatBuffer.put(i, v)
02-29 17:25:39.995: I/javacpp test(25543): capacity(): 3000000
02-29 17:25:40.000: I/javacpp test(25543): pass 0
02-29 17:25:42.050: I/javacpp test(25543): pass 1
02-29 17:25:44.100: I/javacpp test(25543): pass 2
02-29 17:25:46.160: I/javacpp test(25543): Test #1 took 6,162000 seconds.
02-29 17:25:46.160: I/javacpp test(25543): Test #1.1: FloatBuffer.put(array)
02-29 17:25:46.210: I/javacpp test(25543): pass 0
02-29 17:25:46.230: I/javacpp test(25543): pass 1
02-29 17:25:46.270: I/javacpp test(25543): pass 2
02-29 17:25:46.285: I/javacpp test(25543): Test #1.1 took 0,126000 seconds.
02-29 17:25:46.285: I/javacpp test(25543): Test #2: FloatPointer.put(i, v)
02-29 17:25:46.285: I/javacpp test(25543): capacity(): 3000000
02-29 17:25:46.285: I/javacpp test(25543): pass 0
02-29 17:25:47.330: I/javacpp test(25543): pass 1
02-29 17:25:48.325: I/javacpp test(25543): pass 2
02-29 17:25:49.320: I/javacpp test(25543): Test #2 took 3,034000 seconds.
02-29 17:25:49.320: I/javacpp test(25543): Test #3: IntBuffer.put(i, v)
02-29 17:25:49.350: I/javacpp test(25543): capacity(): 3000000
02-29 17:25:49.355: I/javacpp test(25543): pass 0
02-29 17:25:51.360: I/javacpp test(25543): pass 1
02-29 17:25:53.360: I/javacpp test(25543): pass 2
02-29 17:25:55.365: I/javacpp test(25543): Test #3 took 6,013000 seconds.
02-29 17:25:55.365: I/javacpp test(25543): Test #4: IntPointer.put(i, v)
02-29 17:25:55.365: I/javacpp test(25543): capacity(): 3000000
02-29 17:25:55.365: I/javacpp test(25543): pass 0
02-29 17:25:56.295: I/javacpp test(25543): pass 1
02-29 17:25:57.215: I/javacpp test(25543): pass 2
02-29 17:25:58.135: I/javacpp test(25543): Test #4 took 2,771000 seconds.
02-29 17:25:58.135: I/javacpp test(25543): Test #5: IntBuffer.get(i)
02-29 17:25:58.135: I/javacpp test(25543): capacity(): 3000000
02-29 17:25:58.135: I/javacpp test(25543): pass 0
02-29 17:26:00.200: I/javacpp test(25543): pass 1
02-29 17:26:02.255: I/javacpp test(25543): pass 2
02-29 17:26:04.310: I/javacpp test(25543): Test #5 took 6,173000 seconds.
02-29 17:26:04.310: I/javacpp test(25543): Test #6: IntPointer.get(i)
02-29 17:26:04.310: I/javacpp test(25543): capacity(): 3000000
02-29 17:26:04.310: I/javacpp test(25543): pass 0
02-29 17:26:05.235: I/javacpp test(25543): pass 1
02-29 17:26:06.155: I/javacpp test(25543): pass 2
02-29 17:26:07.075: I/javacpp test(25543): Test #6 took 2,765000 seconds.

Original comment by adam.waldenberg@gmail.com on 29 Feb 2012 at 4:32

GoogleCodeExporter commented 8 years ago
So it seems the array writes weren't that slow. However, the other results are 
a real kick in the balls.

I first noticed that that JavaCPP types were much faster when I was 
implementing texture loading in the 3D engine.

It also makes me wonder how "optimized" the array put in buffers actually is...

Again... This is on Android... Maybe on desktop the results are completely 
different.

Original comment by adam.waldenberg@gmail.com on 29 Feb 2012 at 4:36

GoogleCodeExporter commented 8 years ago
Direct NIO buffers in OpenJDK/Sun JDK are really fast:
http://blog.vlad1.com/2011/10/05/looking-at-java-nio-buffer-performance/
Which version of Android is this BTW? Android 2.2 was the first version with a 
JIT compiler. I know it's slower than HotSpot, e.g.:
https://blogs.oracle.com/javaseembedded/entry/how_does_android_22s_performance_s
tack_up_against_java_se_embedded
But I didn't know it sucked THAT much ... ? You're not running Android 2.1 now 
are you? :)

Well, if copying an array in JNI is faster than Buffer.put(array), than I 
should provide that in Pointer. Could you also check this for me? :) We'd have 
to do some JNI coding to find out :(

Original comment by samuel.a...@gmail.com on 29 Feb 2012 at 10:48

GoogleCodeExporter commented 8 years ago
Oh wait a minute, we don't need to code in JNI. We can simply map the memcpy() 
function using JavaCPP, e.g.:

    public static native void memcpy(IntPointer   dst, int[]   src, long n);
    public static native void memcpy(FloatPointer dst, float[] src, long n);
    public static native void memcpy(int[]   dst, IntPointer   src, long n);
    public static native void memcpy(float[] dst, FloatPointer src, long n);

Wow, I'm impressed myself :) Let me know how well that performs... thanks!

Original comment by samuel.a...@gmail.com on 1 Mar 2012 at 7:13

GoogleCodeExporter commented 8 years ago
Tests were done under Android 2.3.4.

I will do a test with memcpy... But yeah, it should be really, really fast.

Original comment by adam.waldenberg@gmail.com on 1 Mar 2012 at 8:04

GoogleCodeExporter commented 8 years ago
You won't believe your eyes... It's even worse than I thought.
Here's the test:

import android.os.Bundle;
import android.util.Log;
import com.ejwa.dinja.javacpptest.HelloNative;
import com.googlecode.javacpp.FloatPointer;
import com.googlecode.javacpp.IntPointer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

public class BasicTestActivity extends Activity {
    long lastTime;
    private long timeSinceLastCall() {
        final long timeToReturn = System.currentTimeMillis() - lastTime;
        lastTime = System.currentTimeMillis();
        return timeToReturn;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.i("javacpp test", "Writing to buffers / pointers");

        Log.i("javacpp test", "Test #1: FloatBuffer.put(array)");
        final FloatBuffer floatBuffer = ByteBuffer.allocateDirect(3000000 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        final float[] floatArray = new float[3000000];
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            floatBuffer.put(floatArray);
            floatBuffer.position(0);
        }
        Log.i("javacpp test", String.format("Test #1 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #2: FloatPointer.memcpy(pointer, array)");
        final FloatPointer floatPointer = new FloatPointer(3000000);
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            HelloNative.memcpy(floatPointer, floatArray, 3000000);
        }
        Log.i("javacpp test", String.format("Test #2 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #3: IntBuffer.put(array)");
        final IntBuffer intBuffer = ByteBuffer.allocateDirect(3000000 * 4).order(ByteOrder.nativeOrder()).asIntBuffer();
        final int[] intArray = new int[3000000];
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            intBuffer.put(intArray);
            intBuffer.position(0);
        }
        Log.i("javacpp test", String.format("Test #3 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #4: IntPointer.memcpy(pointer, array)");
        final IntPointer intPointer = new IntPointer(3000000);
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            HelloNative.memcpy(intPointer, intArray, 3000000);
        }
        Log.i("javacpp test", String.format("Test #4 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Reading from buffers / pointers");
        Log.i("javacpp test", "Test #5: FloatBuffer.get(array)");
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            floatBuffer.position(0);
            floatBuffer.get(floatArray);
        }
        Log.i("javacpp test", String.format("Test #5 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #6: FloatPointer.memcpy(array, pointer)");
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            HelloNative.memcpy(floatArray, floatPointer, 3000000);
        }
        Log.i("javacpp test", String.format("Test #6 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #7: IntBuffer.get(array)");
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            intBuffer.position(0);
            intBuffer.get(intArray);
        }
        Log.i("javacpp test", String.format("Test #7 took %f seconds.", timeSinceLastCall() / 1000f));

        ///////////////////////////////////////////////////////////////////////////////////////////////

        Log.i("javacpp test", "Test #8: IntPointer.memcpy(array, pointer)");
        timeSinceLastCall();
        for (int i = 0; i < 3; i++) {
            Log.i("javacpp test", String.format("pass %d", i));
            HelloNative.memcpy(intPointer, intArray, 3000000);
        }
        Log.i("javacpp test", String.format("Test #8 took %f seconds.", timeSinceLastCall() / 1000f));
    }
}

And here are the results (get ready for an even bigger kick in the nuggets):

03-01 09:44:15.215: I/javacpp test(838): Writing to buffers / pointers
03-01 09:44:15.215: I/javacpp test(838): Test #1: FloatBuffer.put(array)
03-01 09:44:15.320: I/javacpp test(838): pass 0
03-01 09:44:15.360: I/javacpp test(838): pass 1
03-01 09:44:15.390: I/javacpp test(838): pass 2
03-01 09:44:15.410: I/javacpp test(838): Test #1 took 0,129000 seconds.
03-01 09:44:15.410: I/javacpp test(838): Test #2: FloatPointer.memcpy(pointer, 
array)
03-01 09:44:15.410: I/javacpp test(838): pass 0
03-01 09:44:15.420: I/javacpp test(838): pass 1
03-01 09:44:15.425: I/javacpp test(838): pass 2
03-01 09:44:15.430: I/javacpp test(838): Test #2 took 0,019000 seconds.
03-01 09:44:15.430: I/javacpp test(838): Test #3: IntBuffer.put(array)
03-01 09:44:15.530: I/javacpp test(838): pass 0
03-01 09:44:15.550: I/javacpp test(838): pass 1
03-01 09:44:15.580: I/javacpp test(838): pass 2
03-01 09:44:15.595: I/javacpp test(838): Test #3 took 0,107000 seconds.
03-01 09:44:15.595: I/javacpp test(838): Test #4: IntPointer.memcpy(pointer, 
array)
03-01 09:44:15.595: I/javacpp test(838): pass 0
03-01 09:44:15.605: I/javacpp test(838): pass 1
03-01 09:44:15.610: I/javacpp test(838): pass 2
03-01 09:44:15.615: I/javacpp test(838): Test #4 took 0,017000 seconds.
03-01 09:44:15.615: I/javacpp test(838): Reading from buffers / pointers
03-01 09:44:15.615: I/javacpp test(838): Test #5: FloatBuffer.get(array)
03-01 09:44:15.615: I/javacpp test(838): pass 0
03-01 09:44:17.675: I/javacpp test(838): pass 1
03-01 09:44:19.685: I/javacpp test(838): pass 2
03-01 09:44:21.700: I/javacpp test(838): Test #5 took 6,088000 seconds.
03-01 09:44:21.700: I/javacpp test(838): Test #6: FloatPointer.memcpy(array, 
pointer)
03-01 09:44:21.700: I/javacpp test(838): pass 0
03-01 09:44:21.705: I/javacpp test(838): pass 1
03-01 09:44:21.710: I/javacpp test(838): pass 2
03-01 09:44:21.715: I/javacpp test(838): Test #6 took 0,015000 seconds.
03-01 09:44:21.715: I/javacpp test(838): Test #7: IntBuffer.get(array)
03-01 09:44:21.715: I/javacpp test(838): pass 0
03-01 09:44:23.760: I/javacpp test(838): pass 1
03-01 09:44:25.800: I/javacpp test(838): pass 2
03-01 09:44:27.840: I/javacpp test(838): Test #7 took 6,124000 seconds.
03-01 09:44:27.840: I/javacpp test(838): Test #8: IntPointer.memcpy(array, 
pointer)
03-01 09:44:27.840: I/javacpp test(838): pass 0
03-01 09:44:27.845: I/javacpp test(838): pass 1
03-01 09:44:27.850: I/javacpp test(838): pass 2
03-01 09:44:27.855: I/javacpp test(838): Test #8 took 0,014000 seconds.

Just look at IntBuffer.get(array) vs IntPointer.memcpy(array, pointer) f.ex...
It's over 400 times faster using memcpy!

The speed of array reads on buffers is suspiciously close to to doing get(i) 
individually
for the whole array... So i'm guessing that is what's happening on Android.

And yeah, as you can see... put() vs memcpy() is also ~8 times faster in favour 
of memcpy().

Original comment by adam.waldenberg@gmail.com on 1 Mar 2012 at 8:57

GoogleCodeExporter commented 8 years ago
Oh.. I see I messed up the last test a little... Not that it matters :)....

Original comment by adam.waldenberg@gmail.com on 1 Mar 2012 at 8:59

GoogleCodeExporter commented 8 years ago
Wow, direct NIO buffers do suck terribly on Android. (BTW, the size we pass to 
memcpy() is in bytes, so that should be 3000000*4, but it's still at least 2 
times faster while copying the whole array three times!) I'll be adding these 
put(array)/get(array) to Pointer classes, thanks for testing!

Original comment by samuel.a...@gmail.com on 1 Mar 2012 at 9:07

GoogleCodeExporter commented 8 years ago
Yeah sorry, my misstake :)... 

Original comment by adam.waldenberg@gmail.com on 1 Mar 2012 at 9:10

GoogleCodeExporter commented 8 years ago
And get() will be ~100 times faster then ;)... Thats a really big advantage.

Original comment by adam.waldenberg@gmail.com on 1 Mar 2012 at 9:15

GoogleCodeExporter commented 8 years ago
Great, I've modified the Generator to generate code using 
GetPrimitiveArrayCritical() and ReleasePrimitiveArrayCritical() for get()/put() 
bulk methods of the primitive *Pointer classes, so it should be even faster 
than the memcpy() test you've done, but let me know! thanks

Under OpenJDK, the performance is equivalent to direct NIO buffers, which is an 
interesting result on its own:

        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            buffer.position(0); buffer.put(array);
        }
        System.out.println("buffer.put() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            buffer.position(0); buffer.get(array);
        }
        System.out.println("buffer.get() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            pointer.put(array);
        }
        System.out.println("pointer.put() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            pointer.get(array);
        }
        System.out.println("pointer.get() " + (System.currentTimeMillis() - start) + " µs");

buffer.put() 1899 µs
buffer.get() 1894 µs
pointer.put() 1900 µs
pointer.get() 1883 µs

It should make it easier to produce code that does not suck for both mobile and 
desktop ;)

Original comment by samuel.a...@gmail.com on 1 Mar 2012 at 10:56

Attachments:

GoogleCodeExporter commented 8 years ago
Oops, missing a bit of the code up there:

        IntPointer pointer = new IntPointer(1024*1024);
        IntBuffer buffer = pointer.asBuffer();
        int[] array = new int[1024*1024];

Original comment by samuel.a...@gmail.com on 1 Mar 2012 at 10:57

GoogleCodeExporter commented 8 years ago
Running the exact same test under under Android I get the following:

03-02 08:41:52.950: W/javacpp(9270): buffer.put() 6204 µs
03-02 08:54:12.320: W/javacpp(9270): buffer.get() 739370 µs
03-02 08:54:18.675: W/javacpp(9270): pointer.put() 6353 µs
03-02 08:54:24.795: W/javacpp(9270): pointer.get() 6124 µs

buffer.get() is a disaster, But buffer.put() is actually marginally faster in 
this
instance, however, if I tweak the test to the following:

import android.os.Bundle;
import android.util.Log;
import com.googlecode.javacpp.IntPointer;
import java.nio.IntBuffer;

public class BasicTestActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        IntPointer pointer = new IntPointer(1024*1024 * 10);
        IntBuffer buffer = pointer.asBuffer();
        int[] array = new int[1024*1024 * 10];

        long start = System.currentTimeMillis();
        for (int i = 0; i < 5; i++) {
            buffer.position(0);
            buffer.put(array);
        }
        Log.w("javacpp", "buffer.put() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 5; i++) {
            Log.w("javacpp", "pass " + i);
            buffer.position(0);
            buffer.get(array);
        }
        Log.w("javacpp", "buffer.get() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 5; i++) {
            pointer.put(array);
        }
        Log.w("javacpp", "pointer.put() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 5; i++) {
            pointer.get(array);
        }
        Log.w("javacpp", "pointer.get() " + (System.currentTimeMillis() - start) + " µs");
    }
}

I get these results (consistently):

03-02 09:28:04.435: W/javacpp(11009): buffer.put() 481 µs
03-02 09:28:04.435: W/javacpp(11009): pass 0
03-02 09:28:11.555: W/javacpp(11009): pass 1
03-02 09:28:18.670: W/javacpp(11009): pass 2
03-02 09:28:25.750: W/javacpp(11009): pass 3
03-02 09:28:32.835: W/javacpp(11009): pass 4
03-02 09:28:39.915: W/javacpp(11009): buffer.get() 35485 µs
03-02 09:28:40.230: W/javacpp(11009): pointer.put() 316 µs
03-02 09:28:40.545: W/javacpp(11009): pointer.get() 314 µs

So yeah.. Looking good.

Also... It makes me wonder if the same speedup can be seen on desktop when using
less consecutive calls (like in the second test). I dont have a desktop project
with JavaCPP set up, so you'll have to test it :).

Just as an additional test, I also did the following test that I ran a few 
times,
this one is with fewer loops, I also removed the dead slow buffer.get() ;):

import android.os.Bundle;
import android.util.Log;
import com.googlecode.javacpp.IntPointer;
import java.nio.IntBuffer;

public class BasicTestActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        IntPointer pointer = new IntPointer(1024*512);
        IntBuffer buffer = pointer.asBuffer();
        int[] array = new int[1024*512];

        long start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            buffer.position(0);
            buffer.put(array);
        }
        Log.w("javacpp", "buffer.put() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            pointer.put(array);
        }
        Log.w("javacpp", "pointer.put() " + (System.currentTimeMillis() - start) + " µs");

        start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            pointer.get(array);
        }
        Log.w("javacpp", "pointer.get() " + (System.currentTimeMillis() - start) + " µs");
    }
}

And these are the results:

03-02 09:35:50.590: W/javacpp(11350): buffer.put() 72 µs
03-02 09:35:50.620: W/javacpp(11350): pointer.put() 32 µs
03-02 09:35:50.655: W/javacpp(11350): pointer.get() 32 µs
03-02 09:36:16.815: W/javacpp(11350): buffer.put() 43 µs
03-02 09:36:16.845: W/javacpp(11350): pointer.put() 33 µs
03-02 09:36:16.890: W/javacpp(11350): pointer.get() 41 µs
03-02 09:36:26.710: W/javacpp(11350): buffer.put() 113 µs
03-02 09:36:26.755: W/javacpp(11350): pointer.put() 43 µs
03-02 09:36:26.795: W/javacpp(11350): pointer.get() 42 µs
03-02 09:36:28.955: W/javacpp(11350): buffer.put() 94 µs
03-02 09:36:28.990: W/javacpp(11350): pointer.put() 33 µs
03-02 09:36:29.025: W/javacpp(11350): pointer.get() 33 µs
03-02 09:36:33.355: W/javacpp(11350): buffer.put() 81 µs
03-02 09:36:33.395: W/javacpp(11350): pointer.put() 44 µs
03-02 09:36:33.425: W/javacpp(11350): pointer.get() 31 µs

Original comment by adam.waldenberg@gmail.com on 2 Mar 2012 at 8:41

GoogleCodeExporter commented 8 years ago
With OpenJDK and looping only ten times I get results like this:

buffer.put() 27 µs
buffer.get() 20 µs
pointer.put() 22 µs
pointer.get() 21 µs
buffer.put() 22 µs
buffer.get() 20 µs
pointer.put() 21 µs
pointer.get() 21 µs

So, apart from the JIT compiler kicking in a bit late, it does not seem like 
there is much of any difference.

With Dalvik though, it looks like garbage collection is causing some jitter 
with Buffer.put()... and Buffer.get() is basically useless it seems hey?

In any case, Pointer.get()/put() seems to be working well for you, so I'll be 
updating the repository, along with a release (minus Maven, I will have to do 
that another time, as I will be out of the country next week, but thanks for 
updating the Wiki! Feel free to tag it as "Featured" to have it linked from the 
main page whenever it's done.)

Original comment by samuel.a...@gmail.com on 2 Mar 2012 at 9:04

GoogleCodeExporter commented 8 years ago
Sounds great! Looking forward to the release :).

I'll keep hosting copies of the releases in our Maven repo until you get it 
accepted
in the central repository.

Original comment by adam.waldenberg@gmail.com on 2 Mar 2012 at 9:30

GoogleCodeExporter commented 8 years ago
Added to the latest release. And thanks for the Maven repo!

Original comment by samuel.a...@gmail.com on 3 Mar 2012 at 4:51