Как улучшить цикл for для сотен тысяч предметов?- Актуальная проблема с форматированием, что многие элементы - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть древовидная диаграмма с 300k + элементами, которые мне нужно зациклить.Я ожидал, что это займет некоторое время, но оно доходило до того, что казалось, что оно висит.Я вставил оператор println, чтобы отследить, где я нахожусь, и, действительно, когда он добрался до определенных точек, он останавливался на секунду или три, а затем продолжал.В конце концов (около 140 тыс. Дюймов) он полностью остановился, а затем в конечном итоге самостоятельно завершил программу.

Я пытаюсь создать создателя и средства просмотра древовидной диаграммы для моего проекта.Это n-дерево, но не все ветви будут иметь n-дочерних элементов.Однако, чтобы выровнять его так, как мне нужно, мне нужно составить полное дерево со всеми возможными дочерними элементами до указанных размеров, а затем выполнить итерацию по нему, чтобы проверить размеры, изменить размеры, позиции и существование.

//ArrayList<Button[]> buttons is passed in
double width = 0;
double height = 0;

Group g = new Group();
Scene s = new Scene(g);
    Button[] array = buttons.get(buttons.size() - 1);
    int temp = 1;
    for(int i = 0; i < array.length; ++i) {
        Button b = array[i];
        g.getChildren().add(b);
        g.applyCss();
        g.layout();
        width = width > b.getWidth() ? width : b.getWidth();
        height = height > b.getHeight() ? height : b.getHeight();
        g.getChildren().remove(b);
        System.out.println(temp++);
    }

РЕДАКТИРОВАТЬ (потому что я забыл это сказать): сначала я попробовал цикл для каждого, но у него были те же проблемы, поменял его местами, чтобы посмотреть, был ли он лучше, и получил те же результаты

РЕДАКТИРОВАТЬ: первоисточник лага был получен либо для applyCSS (), либо для layout (), но я остаюсь подозрительным, так как он делает паузу на кажущихся случайными, начиная с 16k, и время от времени на всех остальных, пока не умрет между 170k и 300k.

РЕДАКТИРОВАТЬ: я сделал свое собственное решение, игнорируя кнопки-заполнители и, таким образом, игнорируя почти все в дереве, но я держу это открытым в надежде, что кто-то узнает реальное решение и опубликует его, чтобыдругие могут также извлечь выгоду.Проблема в том, чтобы разобраться, как применить CSS и расположить сотни тысяч узлов, чтобы определить их размер

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Не думайте о цикле for-each против обычного цикла, списков массивов и подобных микрооптимизаций, которые могут дать вам не более миллисекунды.Повторение миллиона элементов абсолютно дешево, важно то, что вы делаете с ними.

Это выглядит как утечка памяти, ваше потребление памяти, кажется, увеличивается, затем GC вызывает небольшую паузу, но этоне может восстановить достаточно памяти, поэтому он вызывается с возрастающей частотой, и, наконец, процесс умирает, поскольку это бесполезно.

Возможно, добавленная и затем удаленная кнопка содержит некоторую дополнительную информацию, может быть, сцена или группа.

Попробуйте java -verbose:gc ... или посмотрите внешнюю память.В отладчике проверьте компоненты, чтобы выяснить, какие изменения и остаются после g.getChildren().remove(b).


Рассмотрите возможность повторного создания компонентов, возможно, используйте новый Scene / Group каждые 1000 ButtonS или отпустите кнопки полностью.Обратите внимание, что в визуальных элементах никогда не должно быть долговременных элементов, поэтому, если нужно, воссоздать кнопки на основе ваших данных будет тривиально (еще не видимый Button - дешевая структура данных (и ее создание очень быстрое)., в то время как кнопка на экране может содержать гораздо больше ресурсов).

0 голосов
/ 12 февраля 2019

Вы пробовали использовать расширенный цикл for?Вот пример одного

for (int YourNumberHere : YourArrayHEre) 
{
    Button b = array[i];
    g.getChildren().add(b);
    g.applyCss();
    g.layout();
    width = width > b.getWidth() ? width : b.getWidth();
    height = height > b.getHeight() ? height : b.getHeight();
    g.getChildren().remove(b);
    System.out.println(temp++);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...