Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Ускорить составление TreeView

11
10 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Рисую TreeView из бд:
Код:
void TMainForm::CreateTreeView (void)
{
  TTreeNode *Node;
  auto_ptr<TADOStoredProc>ADOStoredProc1 (new TADOStoredProc(NULL));
  ADOStoredProc1->Active = false;
  ADOStoredProc1->Parameters->Clear();
  ADOStoredProc1->Connection = ADOConnection1;
  ADOStoredProc1->ProcedureName = "Create_TV";

  ADOStoredProc1->Parameters->CreateParameter("@ItemLevel",ftInteger,pdInput, 4, 0);

  ADOStoredProc1->Parameters->ParamByName("@ItemLevel")->Value.intVal = 0;

  ADOStoredProc1->Active = true;

  while (!ADOStoredProc1->Eof)
        {
          int  id = ADOStoredProc1->FieldValues["IDKey"].intVal;
          TTreeNode *Nod = TreeView->Items->Add(NULL, ADOStoredProc1->FieldByName("ItemName")->AsString);
          Nod->Data = (void*)(int)id;
          CreateChildNode(id, Nod, TreeView, ADOConnection1);
          ADOStoredProc1->Next();
        }
  ADOStoredProc1->Active = false;
}
//---------------------------------------------------------------------------

void TMainForm::CreateChildNode (int ParentIndex, TTreeNode *ParentNode)
{
  auto_ptr<TADOStoredProc>Qu(new TADOStoredProc(NULL));
  Qu->Connection = ADOConnection1;
  Qu->Active = false;
  Qu->ProcedureName = "Create_ChildNode";
  Qu->Parameters->CreateParameter("@ParentIndex", ftInteger, pdInput, 4, ParentIndex);
  Qu->Active = true;
  Qu->First();
  while (!Qu->Eof)
        {
         TreeView->Items->AddChild(ParentNode, Qu->FieldByName("ItemName")->AsString);
         TTreeNode *Nod = ParentNode->GetLastChild();
         int IDKey = Qu->FieldValues["IDKey"];
         Nod->Data = (void*)(int)IDKey;
         auto_ptr<TADOStoredProc>Qu1(new TADOStoredProc(NULL));
         Qu1->Connection = ADOConnection1;
         Qu1->Active = false;
         Qu1->ProcedureName = "Create_ChildNode";
         Qu1->Parameters->CreateParameter("@ParentIndex", ftInteger, pdInput, 4, ParentIndex);
         Qu1->Active = true;
         Qu1->First();
         if (Qu1->RecordCount > 0)
              CreateChildNode(Qu->FieldByName("IDKey")->AsInteger, ParentNode->GetLastChild());
         Qu->Next();
        }
}

где:Qu->ProcedureName = "Create_ChildNode";
SQL
 
Код:
CREATE PROC Create_ChildNode (@ParentIndex int)
AS BEGIN
  SELECT IDKey, ParentIndex, ItemName, ItemLevel, Vers, Pos
    FROM base
  WHERE ParentIndex = @ParentIndex and Vers <> 1 order by Pos ASC
END


ADOStoredProc1->ProcedureName = "Create_TV";

SQL
 
Код:
CREATE PROC Create_TV (@ItemLevel int = 0)
 AS BEGIN
 SELECT *
  FROM base
 WHERE ItemLevel = @ItemLevel
END


как можно ускорить этот алгоритм?
92
11 декабря 2007 года
Тень Пса
2.2K / / 19.10.2006
весь алгоритм не смотрел, времени нет, т.к. конец рабочего дня =)

но как минимум для TTreeView::Items можно сделать BeginUpdate() перед началом создания всего дерева, и EndUpdate() - после. это хотябы заставит TTreeView не перерисовываться при каждом изменении, а перерисует только после EndUpdate() 1 раз.
11
13 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Тень Пса
весь алгоритм не смотрел, времени нет, т.к. конец рабочего дня =)

но как минимум для TTreeView::Items можно сделать BeginUpdate() перед началом создания всего дерева, и EndUpdate() - после. это хотябы заставит TTreeView не перерисовываться при каждом изменении, а перерисует только после EndUpdate() 1 раз.



время сократилось на 1мс :D было 68мс, стало 67мс

риторический вопрос, че делать?

92
13 декабря 2007 года
Тень Пса
2.2K / / 19.10.2006
ты еще и в миллисекундах пытаешься сократить время? =)

а ты подумай лучше - это здесь критично? 67 мсек на составление дерева... имхо, нормуль
11
13 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Тень Пса
ты еще и в миллисекундах пытаешься сократить время? =)

а ты подумай лучше - это здесь критично? 67 мсек на составление дерева... имхо, нормуль



пока записей всего ~500 и вложений не так много - 8

а если БД разрастется до нескольких десятков тысяч записей и вложений штук 30 будет?
и сервак ничем щас не занят, только на меня работает

92
13 декабря 2007 года
Тень Пса
2.2K / / 19.10.2006
ну тогда точно оптимизировать запросы :) тут, извини, не помогу (это ж MS SQL если не ошибаюсь)
11
13 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Тень Пса
ну тогда точно оптимизировать запросы :) тут, извини, не помогу (это ж MS SQL если не ошибаюсь)



да MS SQL Server
запросы оптимизированы по самое некуда, больше ниче не викинешь ни добавишь (ИМХО, но рассмотрю другие варианты)

склоняюсь к тому что алгоритм несколько через ж... (с его рекурсиями и авто_птр-ами)
особенно много времени теряется на Qu->Active = true; (ИМХО)

489
13 декабря 2007 года
NeO_u
277 / / 11.10.2006
А не проще ли будет добавить Application->ProcessMessages(), это поможет тебе избежать зависания программы, и добавит в нее динамичность, т.е тебе все равно сколько оно будет загружать все записи, ты все равно сможешь работать с программой.

Так разве не покатит?
11
13 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: NeO_u
А не проще ли будет добавить Application->ProcessMessages(), это поможет тебе избежать зависания программы, и добавит в нее динамичность, т.е тебе все равно сколько оно будет загружать все записи, ты все равно сможешь работать с программой.

Так разве не покатит?



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

Цитата:
ты все равно сможешь работать с программой

)

489
13 декабря 2007 года
NeO_u
277 / / 11.10.2006
У тебя дерево будет прорисовыватся динамически...Т.е. оно будет появляться не сразу, а постепенно. Так, помойму, делают все, когда ускороить процесс не получается:-)
11
13 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: NeO_u
У тебя дерево будет прорисовыватся динамически...Т.е. оно будет появляться не сразу, а постепенно. Так, помойму, делают все, когда ускороить процесс не получается:-)



идею понял, спасибо!

ЗЫ: хотелось бы услышать какие нидь рекомендации по самому алгоритму

11
19 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
В тему, по поводу замера времени:
Сделал программку которая на определенное сообщение детает Timer->Enabled = true; и Timer->Enabled = false; таймаум таймера установил 1мс.
Т.о. из программы которую хочу замерить на тормознутость:
 
Код:
SendMessage (WM_START_TIMER, ...);
CreateTreeView(...);
SendMessage (WM_STOP_TIMER, ...);


сам вопрос: Насколько точно таким макаром можно измерить время выполнения ф-ции, т.е. будул ли задержки на пересылку и обработку сообщения старт/стоп, и насколько влияет приоритет программы-таймера на точность?
92
19 декабря 2007 года
Тень Пса
2.2K / / 19.10.2006
http://forum.codenet.ru/showthread.php?t=15851 здесь посмотрим, по-моему будет лучше так. а то таймер всё-таки жрёт =)
11
20 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
оптимизировал по самое нехочу, вместо 67 мс делает за 1мс (замерял прежним способом)

Код:
void CreateTreeView1 (TADOConnection *ADOConnection1, TTreeView *TreeView)
{
  TTreeNode *Node;
  map <int, TTreeNode*> NodeMap;
  auto_ptr<TADOStoredProc>sp (new TADOStoredProc(NULL));
  sp->Active = false;
  sp->Parameters->Clear();
  sp->Connection = ADOConnection1;
  sp->ProcedureName = "Create_TV1";
  sp->Parameters->CreateParameter("@ID",ftInteger,pdInput, 4, 0);
  sp->Active = true;
  while (!sp->Eof)
        {
          Node = new TTreeNode (TreeView->Items);
          if (sp->FieldByName("ItemLevel")->AsInteger == 0)
             NodeMap[sp->FieldByName("IDKey")->AsInteger] = TreeView->Items->Add(NULL, sp->FieldByName("ItemName")->AsString);
          else
             {
               Node = NodeMap[sp->FieldByName("ParentIndex")->AsInteger];
               NodeMap[sp->FieldByName("IDKey")->AsInteger] = TreeView->Items->AddChild(Node, sp->FieldByName("ItemName")->AsString);
             }
          Node->Data = (void*)(int)sp->FieldByName("IDKey")->AsInteger;
          sp->Next();
        }
}


запрос:

ALTER PROC Create_TV1 (@ID int)
AS BEGIN
 SELECT * FROM base
 ORDER BY ParentIndex, Pos
END


мож кому пригодится
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог