Может ли компилятор Java оптимизировать добавление в набор в рекурсивных методахJAVA

Программисты JAVA общаются здесь
Anonymous
 Может ли компилятор Java оптимизировать добавление в набор в рекурсивных методах

Сообщение Anonymous »

Простой вопрос задается в основном из любопытства о том, что Java Compilers достаточно умны, чтобы сделать. Я знаю, что не все компиляторы построены одинаково, но мне интересно, считается ли другие разумно ожидать оптимизации на большинство компиляторов, с которыми я, вероятно, сталкиваюсь, а не, если она работает на определенной версии или на всех версиях.

Итак, скажем, у меня есть какая -то структура дерева, и я хочу собрать всего потока узла. Есть два простых способа сделать это рекурсивно.
public Set getDescendants(){

Set descendants=new HashSet();
descendants.addall(getChildren());

for(Node child: getChildren()){
descendants.addall(child.getDescendants());
}

return descendants;
}
< /code>

Тем не менее, при условии, что нет оптимизации компилятора и дерева приличного размера, это может стать довольно дорого. При каждом рекурсивном вызове я создаю и полностью заполняю набор, только для того, чтобы вернуть этот стек, чтобы метод вызова мог добавить содержимое моего возвращающегося набора в это версия набора потомков, отбрасывая версию Это было просто построено и населено в рекурсивном вызове. < /p>

Так что теперь я создаю множество наборов, просто чтобы их отказались, как только я возвращаю их содержимое. Я не только оплачиваю незначительную стоимость инициализации за строительство наборов, но и плачу более существенную стоимость перемещения всего содержимого одного набора в более крупный набор. На больших деревьях большая часть моего времени тратится на перемещающиеся узлы в памяти от сета А к Б. Я думаю, что это даже делает мой алгоритм O (n^2) вместо O (n) из -за времени, проведенного копированием узлов; Хотя это может решить, чтобы быть O (n log (n)), если я настроен на математику. вспомогательный метод, который выглядит так: < /p>

public Set getDescendants(){
Set descendants=new HashSet();
getDescendantsHelper(descendants);

return descendants;
}

public Set getDescendantsHelper(Set descendants){

descendants.addall(getChildren());

for(Node child: getChildren()){
child.getDescendantsHelper(descendant);
}

return nodes;
}
< /code>

Это гарантирует, что я когда -либо создаю один набор, и мне не нужно тратить время на копирование от одного набора в другой. Тем не менее, это требует написания двух методов вместо одного и, как правило, кажется немного более громоздким. < /P>

Вопрос в Оптимизация такого рода метода? Или я могу разумно ожидать, что компилятор Java или JIT признать, что я создаю только временные наборы для удобства возвращения к вызову и избежать расточительного копирования между наборами? < /p>

< P> РЕДАКТИРОВАТЬ: Уборка плохой копии вставки, которая приводит к моему образцу метода, добавляя все дважды. Вы знаете, что что -то плохое, когда ваш «оптимизированный» код медленнее, чем ваш обычный код.

Подробнее здесь: https://stackoverflow.com/questions/231 ... ve-methods

Вернуться в «JAVA»