Ускорить составление TreeView
{
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
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
AS BEGIN
SELECT *
FROM base
WHERE ItemLevel = @ItemLevel
END
как можно ускорить этот алгоритм?
но как минимум для TTreeView::Items можно сделать BeginUpdate() перед началом создания всего дерева, и EndUpdate() - после. это хотябы заставит TTreeView не перерисовываться при каждом изменении, а перерисует только после EndUpdate() 1 раз.
но как минимум для TTreeView::Items можно сделать BeginUpdate() перед началом создания всего дерева, и EndUpdate() - после. это хотябы заставит TTreeView не перерисовываться при каждом изменении, а перерисует только после EndUpdate() 1 раз.
время сократилось на 1мс :D было 68мс, стало 67мс
риторический вопрос, че делать?
а ты подумай лучше - это здесь критично? 67 мсек на составление дерева... имхо, нормуль
а ты подумай лучше - это здесь критично? 67 мсек на составление дерева... имхо, нормуль
пока записей всего ~500 и вложений не так много - 8
а если БД разрастется до нескольких десятков тысяч записей и вложений штук 30 будет?
и сервак ничем щас не занят, только на меня работает
да MS SQL Server
запросы оптимизированы по самое некуда, больше ниче не викинешь ни добавишь (ИМХО, но рассмотрю другие варианты)
склоняюсь к тому что алгоритм несколько через ж... (с его рекурсиями и авто_птр-ами)
особенно много времени теряется на Qu->Active = true; (ИМХО)
Так разве не покатит?
Так разве не покатит?
мне то может быть и все равно сколько она будет рисовать, а вот если пару десятков юзеров будут работать с большой базой, то мне не все равно будет то что они обо мне думают, тем более без дерева в ней собственно говоря и делать то нечего (это насчет
)
идею понял, спасибо!
ЗЫ: хотелось бы услышать какие нидь рекомендации по самому алгоритму
Сделал программку которая на определенное сообщение детает Timer->Enabled = true; и Timer->Enabled = false; таймаум таймера установил 1мс.
Т.о. из программы которую хочу замерить на тормознутость:
CreateTreeView(...);
SendMessage (WM_STOP_TIMER, ...);
сам вопрос: Насколько точно таким макаром можно измерить время выполнения ф-ции, т.е. будул ли задержки на пересылку и обработку сообщения старт/стоп, и насколько влияет приоритет программы-таймера на точность?
{
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
мож кому пригодится