I write an OpenGL app in Java using JOGL. I am trying to completely avoid the creation of objects during the main app's phase as it could lead to the small periodic lag caused by GC.
I want to wrap some JOGL's methods with my own. Imagine a method
void method(int[] result, int offset)which receives the pointer to an array and an offset and puts one integer value into it at the specified index. I want to wrap it with simpleint getResult()So I need to create a temporary array somewhere and I must do that in advance (according to 1).
But if it will be stored in a field of the class containing this wrapper method, this will force me to make the wrapper method
synchronized. I know that sychronization in time of mostly single-thread access shouldn't produce a big overhead but I still want to know is it there a better solution for this.
Notes:
- Synchronized is not the answer, 3.000.000 of empty synchronized blocks, just monitorenter-monitorexit take 17 ms. You have only 16.(6) if you want to keep 60 fps.
As I haven't enough power for voting up the only way I found to appreciate Dave's answer is writting a demo:
class Test {
private static final int CYCLES = 1000000000;
int[] global = new int[1];
ThreadLocal<int[]> local = new ThreadLocal<int[]>();
void _fastButIncorrect() { global[0] = 1; }
synchronized void _slowButCorrect() { global[0] = 1; }
void _amazing() {
int[] tmp = local.get();
if( tmp == null ){
tmp = new int[1];
local.set(tmp);
}
tmp[0] = 1;
}
long fastButIncorrect() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _fastButIncorrect();
return System.currentTimeMillis() - l;
}
long slowButCorrect() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _slowButCorrect();
return System.currentTimeMillis() - l;
}
long amazing() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _amazing();
return System.currentTimeMillis() - l;
}
void test() {
System.out.println(
"fastButIncorrect cold: " + fastButIncorrect() + "\n" +
"slowButCorrect cold: " + slowButCorrect() + "\n" +
"amazing cold: " + amazing() + "\n" +
"fastButIncorrect hot: " + fastButIncorrect() + "\n" +
"slowButCorrect hot: " + slowButCorrect() + "\n" +
"amazing hot: " + amazing() + "\n"
);
}
public static void main(String[] args) {
new Test().test();
}
}
on my machine the results are:
fastButIncorrect cold: 40
slowButCorrect cold: 8871
amazing cold: 46
fastButIncorrect hot: 38
slowButCorrect hot: 9165
amazing hot: 41
Thanks again, Dave!