Мой код в основном свободен для выделения, однако GC запускается каждые 30 секунд или около того, когда скорость составляет 60 кадров в секунду.Проверка приложения с DDMS на выделение показывает, что выделено ALOT SimpleListIterator
.Есть также некоторые вещи, которые выделяются, потому что я использую Exchanger
.
SimpleListIterator поставляется для каждого цикла for (T obj : objs) {}
.У меня сложилось впечатление, что компилятор / переводчик оптимизировал бы их, чтобы они не использовали итераторы для типов, которые его поддерживают (я в основном использую только ArrayList), но, похоже, это не так.
Как можно избежать выделения всехэти SimpleListIterators
?Одним из решений было бы переключение на обычные циклы for for (int i = 0; i < size; ++i) {}
, но мне нравится для каждого цикла: (
Другим способом было бы расширение ArrayList, который возвращает Iterator
, который выделяется только один раз.
Третий способ, который я взломал вместе, - это использование статической вспомогательной функции, которая возвращает Collection
, который повторно использует Iterator
. Я взломал что-то подобное вместе, но кастинг выглядит очень хакерским и небезопасным.Я использую ThreadLocal
? См. Ниже:
public class FastIterator {
private static ThreadLocal<Holder> holders = new ThreadLocal<Holder>();
public static <T> Iterable<T> get(ArrayList<T> list) {
Holder cont = holders.get();
if (cont == null) {
cont = new Holder();
cont.collection = new DummyCollection<T>();
cont.it = new Iterator<T>();
holders.set(cont);
}
Iterator<T> it = (Iterator<T>) cont.it;
DummyCollection<T> collection = (DummyCollection<T>) cont.collection;
it.setList(list);
collection.setIterator(it);
return collection;
}
private FastIterator() {}
private static class Holder {
public DummyCollection<?> collection;
public Iterator<?> it;
}
private static class DummyCollection<T> implements Iterable {
private Iterator<?> it;
@Override
public java.util.Iterator<T> iterator() {
return (java.util.Iterator<T>) it;
}
public void setIterator(Iterator<?> it) {
this.it = it;
}
}
private static class Iterator<T> implements java.util.Iterator<T> {
private ArrayList<T> list;
private int size;
private int i;
@Override
public boolean hasNext() {
return i < size;
}
@Override
public T next() {
return list.get(i++);
}
@Override
public void remove() {
}
public void setList(ArrayList<T> list) {
this.list = list;
size = list.size();
i = 0;
}
private Iterator() {}
}
}