Closed GoogleCodeExporter closed 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
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
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
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
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
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
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
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
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
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
Yeah sorry, my misstake :)...
Original comment by adam.waldenberg@gmail.com
on 1 Mar 2012 at 9:10
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
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:
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
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
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
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
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
Original issue reported on code.google.com by
adam.waldenberg@gmail.com
on 29 Feb 2012 at 9:50