Я пишу приложение OpenGL в Java, используя JOGL. Я пытаюсь полностью избежать создания объектов во время фазы основного приложения, так как это может привести к небольшому периодическому отставанию, вызванному GC.Как избежать синхронизации и создания объектов?
Я хочу обернуть некоторые методы JOGL своим. Представьте способ
void method(int[] result, int offset)
, который получает указатель на массив и смещение и помещает в него одно целое значение по указанному индексу. Я хочу обернуть его простымint getResult()
Поэтому мне нужно создать временный массив где-нибудь, и я должен сделать это заранее (согласно 1).
Но если он будет сохранен в поле класса, содержащего этот метод обертки, это заставит меня сделать метод обёртки
synchronized
. Я знаю, что синхронизация во времени, в основном, однопоточного доступа, не должна создавать больших накладных расходов, но я все еще хочу знать, есть ли там лучшее решение для этого.
Примечание:
- Синхронный не является ответом, 3.000.000 из пустых синхронизированных блоков, просто monitorenter-monitorexit принять 17 мс. У вас всего 16. (6), если вы хотите сохранить 60 кадров в секунду.
Как я уже не хватает мощности для голосования до единственный способ, которым я нашел, чтобы оценить ответ Дейва сочинительство демо:
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();
}
}
на моей машине результаты:
fastButIncorrect cold: 40
slowButCorrect cold: 8871
amazing cold: 46
fastButIncorrect hot: 38
slowButCorrect hot: 9165
amazing hot: 41
Еще раз спасибо, Дэйв!
1. Звучит как преждевременная озабоченность. –
@ Комментарий MattBall - это место. У вас есть профайлер, который показывает задержку GC? Если у вас нет достаточного уровня пропускной способности объекта, это не должно быть проблемой. – Gray
Пожалуйста, не обсуждайте характер вопроса. Разве нет решения для этого без синхронизации и без создания объекта? – Grief