Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: построение дерева в mfc  (Прочитано 15393 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
SVoin
Гость
« : 05-07-2006 07:46 » 

Народ, передо мной стоит задача нарисовать дерево по xml файлу. Я это сделал - дерево рисуестя, все как надо. НО, как всегда это "но", если я возьму большой xml файл ( более 2МБ ), то прога просто зависает и памяти ест столько!!.  Можно ли в mfc нарисовать чать дерева, отобразить его для пользователя, освободить память и рисовать дальше (в памяти), ну естесственно потом все это повторять. Т.е. чтоб пользователь мог видеть процесс работы проги.

Еще было бы круто сделать второй поток. который позволили бы юзеру просматривать уже нарисованное дерево. Или это совсем сьест память?


ЗЫ. Всем спасибо за ответ )
Записан
SVoin
Гость
« Ответ #1 : 05-07-2006 07:51 » 

Забыл дополнить дерево рисуется с помощью CTreeCtrl
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #2 : 05-07-2006 11:16 » 

Покажи код, как ты "рисуешь"? MFC не содержит своего собственного объекта типа "дерево", а только оболочку (wrapper - CTreeCtrl) для системного контролла типа SysTreeView32. Тут уж ничего не поделаешь. Заполнять дерево надо полностью. Прорисовывается только "видимая" часть дерева. Так что дело не в этом. Сколько узлов ты видишь в окне? Скорее всего ты делаешь что-то неправильно (неоптимально). Какой XML парсер ты используешь? Попробуй отключить для начала иконки. Нуу в общем побольше информации - "код в студию".
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 05-07-2006 11:17 » 

Второй поток делать не надо, в нормальной ситуации - пользователь видит незменную "первую страницу" и только изменения в вертикальной полосе прокрутки. Те именно то, что ты хочешь (как я понял).
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
SVoin
Гость
« Ответ #4 : 06-07-2006 10:46 » 

В общем, я юзаю написанную когда- то SAX parsing, который читает теги xml'я и создает статус типа: старт тэг, текст, коммент, энд тэг... и т.д. Все это делает парсинг.

Я создал класс который вылавливает этот статус и там рисует дерево, что то в этом духе:
Код:
в h файле 2 переменные
private:
    CTreeCtrl & m_Leaf;  // сюда мы пеердаем наш обьект дерева, с помощью которого все и рисуем
    HTREEITEM Parent;   // а это радитель узлов


cpp файл
CDrawTree::CDrawTree(CTreeCtrl & m_Tr)
:m_Leaf(m_Tr)
{
    Parent = NULL;
}

.......


int CDrawTree::StartTag(CString name)
{
    if (Parent == NULL)
               Parent = m_Leaf.InsertItem(name,1,1);
    else
              Parent = m_Leaf.InsertItem(name,1,1, Parent);
    return 0;
}

// тут рисуем атрибуты которые указаны в теге хмл файла
int CDrawTree::DrawAttribute(CString name, CString value)
{
    HTREEITEM _parent = m_Leaf.InsertItem(name,4,4, Parent);
    if ( value.Trim(" ").GetLength() == 0)
        m_Leaf.InsertItem("[space]",5,5,_parent);
    else
        m_Leaf.InsertItem(value,2,2,_parent);
    return 0;
}

// тут текст между тегом
void CDrawTree::DrawText(CString value)
{
    if(value != "")
    {
        if (value.Trim(" ").GetLength() == 0)
            m_Leaf.InsertItem("[space]",5,5,Parent);
        else
            m_Leaf.InsertItem(value,2,2,Parent);
    }
       

}

int CDrawTree::EndTag(CString name)
{
    if (Parent != NULL)
    {
        Parent = m_Leaf.GetParentItem(Parent);
    }
    return 0;
}



А это процесс вызова методов:

void Roundtrip::writeToken()
{
    switch (parser.getEventType())
    {
                          ...

    case XmlPullParser::START_TAG :
        {
            drawing.StartTag(parser.getName());           
            for (int i = 0; i < parser.getAttributeCount(); i++)
            {
                drawing.DrawAttribute( parser.getAttributeName(i),  parser.getAttributeValue(i));
            }
        }
        break;
    case XmlPullParser::END_TAG :
        drawing.EndTag(parser.getText());
        break;
    case XmlPullParser::TEXT :
        drawing.DrawText(parser.getText());
        break;

                                                      ...


    default :
        throw new XmlPullParserException("unrecognized event: ","",0,0);
    }
}

void Roundtrip::roundTrip()
{     
    while (parser.getEventType() != XmlPullParser::END_DOCUMENT) // получаем статус
    {
        writeToken();       
        parser.nextToken();  //читаем файл далее       
    }
    writeToken();
}


Ну естественно все это рисуется в каком то диалоговом окне, в котором и лежит контрол

В классе этого диалогового окна и происходит инициализация
DDX_Control(pDX, IDC_XML_TREE, m_Tree)     а также  ImageList

там и происходит создание обектов классов для работы с деревом

Код:
 try
      {
          std::ifstream ifs;
          ifs.open(fileName);
          XmlPullParser xpp(ifs);

          CDrawTree dr(m_Tree);
         
          Roundtrip rt(xpp,dr);
          rt.roundTrip();
      }




Когда парсинг запускаеш в консоле - память минимум, но и вид никакой того что там выводится, поэтому и было сделано это мфсишное приложение. Запускаеш маленький файлик - все кульно - 6Кб берет памяти (смотрю в таск менеджере ).
Запускае большой файл - и полетело... зависон и 70Кб

По логике это дерево память ест, сам парсинг элементарен, в этом плане, до безобразия
« Последнее редактирование: 19-12-2007 19:48 от Алексей1153++ » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 06-07-2006 15:01 » 

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

Ближе к телу - ща вермени мало, бегло глянул - вроде всё нормально. А о каком количестве данных идёт речь (сколько Items - примерно)? Какой расход памяти и какая задержка по времени?

Я тут ща попробовал

Код:
void CFastTreeDlg::OnButton1() 
{
m_tree.DeleteAllItems();

HTREEITEM htiRoot = m_tree.InsertItem(_T("root"),0,0);

if(UpdateData(TRUE))
{
for(UINT i=0;i<m_nNodes;i++)
{
CString stItemName;
stItemName.Format(_T("Root_Item_%04d"),i);
HTREEITEM htiChild = m_tree.InsertItem(stItemName,0,0,htiRoot);
for(UINT j=0;j<m_nChilds;j++)
{
stItemName.Format(_T("Child_Item_%04d_%04d"),i,0);
m_tree.InsertItem(stItemName,0,0,htiChild);
}
m_tree.Expand(htiChild, TVE_EXPAND);
}
m_tree.Expand(htiRoot, TVE_EXPAND);
}

}

P4 2GHz 1G RAM - на 1000 узлов, каждый их которых содержит 1000 подузлов (общее число 1 000 000) у меня ушло около 30 секунд, прога заняла в памяти 135 МБайт. Освобождение памяти потребовало больше минуты. Это в debug, в release соответственно 15 сек и 109 МБ, освобождение из памяти 2 сек

При уменьшении числа подузлов в 10 раз (те общее число - 100 000) время "упало" до двух секунд и потребовало 15 МБ памяти (debug). А 100 000 это довольно много.


* Fasttree.zip (32.55 Кб - загружено 1020 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
SVoin
Гость
« Ответ #6 : 06-07-2006 16:41 » 

в общем открыла я xml файл для приблизительного подсчета узлов путем узнавания количества замен символа "/>"  - блокнот повесился мин на 3. Счас нету времени все это засекать. Прийду домой и гляну. А потом выложу результаты
Записан
SVoin
Гость
« Ответ #7 : 10-07-2006 12:32 » 

>Ближе к телу - ща вермени мало, бегло глянул - вроде всё нормально. А о каком количестве данных идёт речь (сколько Items - примерно)? Какой расход памяти и >какая задержка по времени?


Items  - примерно 25 000, памяти всего 512, хотя 2 проца по 2.4 , но мой комп безнадежно повис, но перед этим прога заняла в памяти 175 МБайт.

В общем надо решать проблему больших деревьев, но т.к. я с mfc мало знаком, то я НЕ знаю как.

Может есть какиелибо методы, я думаю многие с этим сталкивались
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 10-07-2006 13:50 » 

25 тыс - это не нагрузка, я же показал, что для 100 000 оно просто "летает".
Если не секретно - кинь проект и файл, который открываешь, на мыло. Я гляну. А то так гадаем на кофейной гуще. Если секретно, попробуй выделить в небольшой проектик ту часть, которая дерево строит и туда же, на мыло. Тут заморочка в чём-то другом. Поэтому быстрее и проще в рабочий код глянуть.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
SVoin
Гость
« Ответ #9 : 19-07-2006 06:01 » new

Джон, я там отправил тебе на мыло дерево.... Как я понял проблема в большем количестве итемсов, есть ли какое-нибуть решение у mfc в таких случаях?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 19-07-2006 18:03 » 

SVoin, всё получил - заминка с 2005 студией - ща под рукой нет.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 19-07-2006 18:28 » 

Джон, SVoin, мммм... и вообще - дерево не строят, а выращивают Улыбаюсь)
(сорри, хулиганское настроение Улыбаюсь )
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 26-07-2006 22:54 » 

Для информации (если автор не пожелает другого - тему можно удалить)
Ну вроде всё прояснилось:

1. Под "рисованием" подразумевалось добавление элементов в контрол типа CTreeCtrl

2. Тормоза оказались в XML-парсере, а не в дереве.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines