Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 31.05.2010
Сообщений: 22
1

Оптимизация кода для вывода категорий.

14.08.2010, 11:46. Просмотров 1398. Ответов 11
Метки нет (Все метки)

Здравствуйте. У меня есть таблица с категориями примерно с такой структурой.

SQL
1
2
3
4
5
6
7
category
-------------------
id parent name 
1  0      Java
2  1      Jsp
3  1      Flex
-------------------
На самом деле в таблице более 10 тысяч записей и со временем станет больше.

Эта программа выведит таблицу в таком виде:
Java / Jsp
Java / Flex


Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void Tree(int id) {
        if (id == 0) {
            return;
        }
 
        try {
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("select * from `category` where `id`=" + id + " limit 1;"); // жрёт много памяти
 
            while (rs.next()) {
                Tree(rs.getInt("parent"));
                parent = rs.getString("name");
                name += parent + " / ";
            }
        } catch (SQLException e) {
            logger.error(e);
        }
    }
Казалось бы все отлично работает. Но мне необходимо вызывать
Tree(n); Более 10 тысяч раз чтобы записать результат метода в
другую таблицу но генерится java.lang.OutOfMemoryError: Java heap space из за 8 строки.
Есть ли способ оптимизировать код чтоб он не жрал столько памяти.
Или может быть есть другой алгоритм для работы с категориями.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.08.2010, 11:46
Ответы с готовыми решениями:

Оптимизация кода вывода текста в консоль
Чего-то я совсем запутался... Так как есть - работает, но понимаю, что это ужасно. Собственно...

Условие if для вывода категорий
Есть условие @if($menu->category_id !=49 &&...

Оптимизация методом Ньютона (нахождение точки минимума). Оптимизация кода
MATLAB только начал осваивать. Попытался реализовать нахождение точки минимума методом Ньютона...

Оптимизация кода для повышения скорости выполнения?
Есть ли какая возможность в VBA замера производительности как в 1С с указанием относительного...

11
Mobile Developer
237 / 233 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.08.2010, 11:59 2
а что возвращает эта строка???
Java
1
 ResultSet rs = stmt.executeQuery("select * from `category` where `id`=" + id + " limit 1;");
как я понимаю одну строку? если селекция по ID, а ID разные?
и что тогда Tree()?? бинарное дерево или?
почему и зачем рекурсивно в цикле вызывается дерево?
ИМХО ,если я правильно представляю , вся проблема тут в цикле... у тебя с каждым новым рекурсивным вызовом дерева, цикл будет идти паралельно старому(вплане выполнять тоже самое что и предыдущие). в чем такая необходимость?
0
0 / 0 / 0
Регистрация: 31.05.2010
Сообщений: 22
14.08.2010, 12:57  [ТС] 3
К примеру вызываем Tree(2) ResultSet вернёт parent=1 (это родитель)
после этого в цикле вызываем Tree(1) (как это видно в коде) но замете экземпляр метода Tree(2) ещё не завершён он ждет завершения Tree(1). когда Tree(1) выполняется к name прибавляется Java, а когда
заканчивает то продолжает своё выполнение Tree(2) и конкатенирует name Jsp. Поэтому ни чего
там параллельно не выполняется.
0
Mobile Developer
237 / 233 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.08.2010, 13:52 4
я же написал что не про паралельное выполнение.
приведу тебье простой пример и я думаю поймешь что я имел ввиду и вчем проблема.
допустим
rs получает строку, затем начинается цикл с условием ПОКА СУЩЕСТВУЮТ ЕЩЕ СТРОКИ выполнять цикл.из этого цикла вызывается дерево.таким образом начальный ID=1, после входа в цикл стал ID=2 ,так же допустим что есть еще ID 3 ,4,5, и т.д. после вызова tree(2) твой цикл не прекращает работу он бесконечно вызывает tree(2) , а из каждого tree(2) вызывается tree(3) и так же зацикливается. Так как в while(rs.next()) нету прироста(продвижения, т.е. твое условие остается неизменным постоянно) rs т.е. он просто проверяет , что у какого-то rs есть next и так происходит зацикливание.
Если правильно представляю твою затею, то поставь if(rs.next()) вместо while(rs.next())
0
0 / 0 / 0
Регистрация: 31.05.2010
Сообщений: 22
14.08.2010, 14:29  [ТС] 5
Программа работает немного не так как ты это скорее всего представляешь.
Во первых категории строятся не от родителя к потомку а от потомка к родителю т.е
SQL
1
2
2 Jsp
  1 Java
а не на оборот. Во вторых tree(2) не сможет вызываться до бесконечности потому как последний parent имеет значение 0 т.е tree(0) такой запрос ни чего не вернёт и метод остановится.
А в третьих можно поставить и if но это не важно потому что while работает пока условие истинно в этом случае оно истинно всегда 1 раз.
0
Mobile Developer
237 / 233 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.08.2010, 14:52 6
выхода из цикла нету=) ты походу с рекурсией запутался. первый раз зашел в цикл вызвалось дерево(2) допустип в какой то момент завершилось рекурсивное выполненеие . но изначально начатый цикл не прерывается.... посмотри внимательно на конструкцию while своего, нет условия для выхода
у тебя конец выполнения рекусрии когда дерево(0) а вот дерево(n>0) никогда не прекратится в цикле будет все время вызываться дерево(n)

Добавлено через 34 секунды
Посмотри в дебаггере именно на этот цикл проведи его доконца только для примера возьми 10 строк например

Добавлено через 8 минут
Пример:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
tree(5)
   5!=0 then
   rs=something
   while(rs.next()) do //нет выхода из цикла постоянные вызовы tree(4)
       tree(4);
   end
end tree(5)
tree(4)//
   4!=0
  rs=something
  while(rs.next()) do //нет выхода из цикла постоянные вызовы tree(3)
      tree(3);
  end
end tree(3)//
 
//etc...
 
tree(1)
    1!=0 then
    while(rs.next()) do //нет выхода из цикла постоянные вызовы tree(0)
        rs=something;
        tree(0);
    end
end tree(1)
 
tree(0)
 0=0 then
 return;
end tree(0)//Возврат в tree(1)
0
0 / 0 / 0
Регистрация: 31.05.2010
Сообщений: 22
14.08.2010, 15:09  [ТС] 7
выхода из цикла нету=) ты походу с рекурсией запутался.
Как это не может быть выхода из цикла rs.next() для чего? rs.next() возвращает false
, а это уже и есть выход из цикла. Тем более экземпляр ResultSet создаётся для каждого нового вызова метода.
А если в базе нет нулевого id то rs.next() изначально будет false тогда метод уже нее будет вызываться
0
Mobile Developer
237 / 233 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.08.2010, 15:16 8
Цитата Сообщение от Zhazhah Посмотреть сообщение
Как это не может быть выхода из цикла rs.next() для чего? rs.next() возвращает false
, а это уже и есть выход из цикла. Тем более экземпляр ResultSet создаётся для каждого нового вызова метода
ну так я понимаю что rs.next() проверяет сущзествует ли след рс или нет.
но вот он зашел в tree(5) rs=4 (например) rs.next=3 соответственно rs.next() будет возвращать true
и так как rs остается все тем же rs=4 в цикле tree(5) => rs.next() всегда true;
короче попробуй if вместо while и увидишь сам.
ПыСы
в дебаггере смотрел вообще??!
0
0 / 0 / 0
Регистрация: 31.05.2010
Сообщений: 22
14.08.2010, 15:32  [ТС] 9
ну так я понимаю что rs.next() проверяет сущзествует ли след рс или нет.
Нет он не проверяет на существование следующий rs. Это таблица с данными которые удалось найти в базе. А если ни чего не найдено то rs.next() == false.
Также rs=4 ни как не связан с rs=3 потому что объект ResultSet создаётся при каждом новом вызове метода ведь это не глобальная переменная которая могла бы действовать на цикл так как ты говоришь.
Я пробовал if вместо while результат как и ожидалось прежний.
0
Mobile Developer
237 / 233 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.08.2010, 15:56 10
кинь весь код ...
и что дебаггер говорит?!
0
632 / 524 / 165
Регистрация: 01.04.2010
Сообщений: 1,843
16.08.2010, 12:55 11
По-моему, подход изначально неверный. Посмотри как в swing реализовано дерево (JTree + TreeModel + TreeNode) и сделай подобное. Все на самом деле просто, я сейчас пример найти не могу, но у меня похожая задача была, и решалась она за 1 запрос типа "select * from table"
0
30 / 24 / 7
Регистрация: 27.05.2010
Сообщений: 99
17.08.2010, 03:10 12
раз запрос жрет много памяти
зачем делать его много раз?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.08.2010, 03:10

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Оптимизация кода для ускорения работы прораммы
Как оптимизировать эту функцию чтоб она выполнялась за 1 секунду. unsigned long peak(unsigned...

Оптимизация кода скрипта для работы с архивами
Оптимизация скрипта, для работы с архивами / О форуме и сайтах Есть скрипт, текст ниже. Что он...

Ошибка вывода категорий smarty
Есть база данных хранящая статьи и я пытаюсь эти статьи вывести в левое меню, если вывести их в...

Оптимизация кода пакетного файла для создания бэкапов
Добрый день. Столкнулся с задачей: требуется оптимизировать создание бэкапов. деление на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.