Вопрос про TQuery
Окошко плавает, все рисуется. Данные при этом (т.е. сам график) берутся из базы данных. Сейчас я при каждой перерисовке (а она, естественно, происходит и при изменении размеров окна, и при его перемещении) открываю запрос и в цикле читаю данные и строю графики:
MyQuery1->Open();
do
{
// построение графика1
}
while (МуQuery1->FindNext()!=NULL);
MyQuery1->Close();
...............
...............
MyQueryN->Open();
do
{
// построение графикаN
}
while (МуQueryN->FindNext()!=NULL);
MyQueryN->Close();
Таким образом, всякий раз теряю драгоценное время
на выполнение запросов.
Я решил все запросы выполнять в конструкторе (чтобы списки заполнить), т.е. при создании графика.
При этом есть две альтернативы:
1) Создать достаточное количестов списков (по числу графиков), выполнить запросы и заполнить списки в конструкторе. При этом, при первом отображении графика все циклы выполняются два раза: сначала в конструкторе, а потом при его отрисовке.
2) Открыть в конструкторе запросы, т.е.
МуQuery1->Open();
MyQuery2->Open();
...........
...........
...........
MyQueryN->Open();
а циклы поместить в функцию отрисовки графика.
Здесть, очевидно, циклы будут выполняться всего один раз для каждой отрисовки.
В связи с этим вопрос: Не много ли ресурсов жрет второй способ? Т.к. поддерживается одновременно много соединений с базой (может быть одновременно много плавающих окошек, в которых, в свою очередь, много графиков). Не будут ли при этом тормозиться другие запросы, с графиками не связанные? Вообще, какой способ выгоднее - 1-й ли 2-й? Мож. кто-нибудь что-нибудь более остроумное предложит :)?
Заранее спасибо.
а вообще количество соединенийс базой определятся не количеством открытых TQuery
а количеством созданных объектов TSession
те если у тебя один TDatabase и 100 TQuery
то если явно не указывать TSession все TQuery будут использовать одно и то же соединение...
Сейчас я при каждой перерисовке (а она, естественно, происходит и при изменении размеров окна, и при его перемещении) открываю запрос и в цикле читаю данные и строю графики:
...
При этом есть две альтернативы:
...
Не очень понятно - зачем вызывать запросы при каждой перерисовке? Если предполагается динамическое обновление данных - имеет смысл обновлять данные по какому либо событию - самый простой - по таймеру, но лучше использовать оконные сообщения - т.е. пользователь изменил что либо в данных - посылается зарегистрированное тобой сообщение и только после этого данные перечитываются. Если же графики - статические, что кстати следует из твоего сообщения - смысла в этом нет никакого - если винда не может корректно отрисовать твое окно(почему то?) - отрисовуй его сам - но это в любом случае будет быстрее чем вычитка новых данных. Копирование картинки в оперативку и из нее пожалуй на несколько порядков будет быстрее чем выполнение даже небольшого запроса.
Вариант со списками менее накладен, если оперативки в достатке - но здесь лучше использовать динамические массивы - они более эффективны по скорости доступа, чем списки - ведь чтение у тебя все равно последовательное.
Делаю плавающие графики как в Excel'e.
Окошко плавает, все рисуется. Данные при этом (т.е. сам график) берутся из базы данных. Сейчас я при каждой перерисовке (а она, естественно, происходит и при изменении размеров окна, и при его перемещении) открываю запрос и в цикле читаю данные и строю графики:
MyQuery1->Open();
do
{
// построение графика1
}
while (МуQuery1->FindNext()!=NULL);
MyQuery1->Close();
...............
...............
MyQueryN->Open();
do
{
// построение графикаN
}
while (МуQueryN->FindNext()!=NULL);
MyQueryN->Close();
Таким образом, всякий раз теряю драгоценное время
на выполнение запросов.
Я решил все запросы выполнять в конструкторе (чтобы списки заполнить), т.е. при создании графика.
При этом есть две альтернативы:
1) Создать достаточное количестов списков (по числу графиков), выполнить запросы и заполнить списки в конструкторе. При этом, при первом отображении графика все циклы выполняются два раза: сначала в конструкторе, а потом при его отрисовке.
2) Открыть в конструкторе запросы, т.е.
МуQuery1->Open();
MyQuery2->Open();
...........
...........
...........
MyQueryN->Open();
а циклы поместить в функцию отрисовки графика.
Здесть, очевидно, циклы будут выполняться всего один раз для каждой отрисовки.
В связи с этим вопрос: Не много ли ресурсов жрет второй способ? Т.к. поддерживается одновременно много соединений с базой (может быть одновременно много плавающих окошек, в которых, в свою очередь, много графиков). Не будут ли при этом тормозиться другие запросы, с графиками не связанные? Вообще, какой способ выгоднее - 1-й ли 2-й? Мож. кто-нибудь что-нибудь более остроумное предложит :)?
Заранее спасибо.
Все TQuery хранят результаты запросов на локальном диске в temp директории. И пресоздают их при каждом методе Open. Если Open делать один раз, то тормоза не будет. В варианте со списком ты займешь гораздо больше ОЗУ. А это может привести к тормозу других приложений и к ненужному свопингу.
2 kot_ графики у меня действительно статические. Они в отдельных окошках, поэтому должны перерисовываться всякий раз при изменении размеров окна или его перемещении. Хранить картинку в оперативке, ИМХО, нездорово, т.к. возникнут некоторые проблемы с масштабированием особенно с масштабированием шрифтов и т.п. Запросы при каждой отрисовке сделал, т.к. делал в "первом приближении", теперь отлаживаю. Заменю по твоему совету в своей проге все списки на динамические массивы.
2AlexandrVSmirno Отлично!
Еще раз всем спасибо.
Хранить картинку в оперативке, ИМХО, нездорово, т.к. возникнут некоторые проблемы с масштабированием особенно с масштабированием шрифтов и т.п.
Это все целиком зависит от того, что ты пытаешься сделать. Если горят сроки, лень, бесплатная работа, единственная задача этой программы - или еще какая причина - забей и делай как проще.
Но ни кто и не предлагает хранить картинку в оперативке - и кстати какие проблемы при этом собственно могут возникнуть?:D
По возможности стоит использовать механизмы ОС, а не придумывать велосипед себе же на ж.... Если система не велика - вариант с запросами сгодится под пиво. Если же планируешь(требуют) сделать качественную программу - без механизма сообщений тебе обойтись не получится и тогда отрисовка окон запросом+система массивов(списков) будет у тебя самым сильным тормозом из за которого прийдется переписать программу, где бы они не хранились, тем более, что чтение с диска - на сегодняшний день не самая быстрая из операций. А работа с базой как правило имеет тенденцию очень быстро перерастать из локальной в сетевую.
Это все целиком зависит от того, что ты пытаешься сделать. Если горят сроки, лень, бесплатная работа, единственная задача этой программы - или еще какая причина - забей и делай как проще.
Но ни кто и не предлагает хранить картинку в оперативке - и кстати какие проблемы при этом собственно могут возникнуть?:D
По возможности стоит использовать механизмы ОС, а не придумывать велосипед себе же на ж.... Если система не велика - вариант с запросами сгодится под пиво. Если же планируешь(требуют) сделать качественную программу - без механизма сообщений тебе обойтись не получится и тогда отрисовка окон запросом+система массивов(списков) будет у тебя самым сильным тормозом из за которого прийдется переписать программу, где бы они не хранились, тем более, что чтение с диска - на сегодняшний день не самая быстрая из операций. А работа с базой как правило имеет тенденцию очень быстро перерастать из локальной в сетевую.
Ты прав безусловно. Поэтому я и отказался от запросов при отрисовке (я и сделал-то так временно, чтобы побыстрее все заработало). Данные будут храниться либо в динамических массивах, либо я просто открою для каждого окошка n-ое количесво Query (т.е. выполню запросы один раз при создании графика) и при отрисовке буду читать данные. Посмотрю что быстрее. Подумаю насчет хранения картинки в оперативке, это заманчиво, но здесь у меня действительно возникают специфические проблемы: у меня при изменении размеров окна, меняется сетка, т.е. меняется количество линий сетки, шаг по оси ординат, временная шкала по оси абсцисс и т.п.
С уважением, Кролик :)
Я в принципе графикой первый раз занимаюсь.
У меня в OnPaint каждый раз идет отрисовка графика. Если можно без этого обойтись, то как?
Кинь общую идею, а я уж гугле посмотрю подробности.
А может я тебя не понял просто?
Я в принципе графикой первый раз занимаюсь.
У меня в OnPaint каждый раз идет отрисовка графика. Если можно без этого обойтись, то как?
Кинь общую идею, а я уж гугле посмотрю подробности.
Может и не понял - или я плохо объяснил. Дело в том, что график то у тебя нарисован при создании формы - и тебе не нужно рисовать его каждый раз заново - тебе достаточно его просто копировать. А реализовать это можно как минимум двумя способами -
Первый и самый простой - это использование Image:
pBitmap->Height = 150;
pBitmap->Width = 150;
pBitmap->Canvas->LineTo(100,100);
Image1->Canvas->Draw(0,0,pBitmap);
delete pBitmap;
в конструкторе или функции-рисовалке - а дальше компонент будет уж сам отрабатывать то что необходимо.
Как вариант этого способа - создание в классе формы объекта TBitmap и рисование на нем. Потом в событиях отрисовки формы просто копирование его на форму.
Второй гораздо сложнее и требует работы с собщениями - т.е. перехват сообщений WM_PAINT, WM_SCROLL,WM_CLOSE и т.д. - сохранение текущего контекста окна и перерисовка при востановлении.
Мы в подобной ситуации пошли по пути разработки трех классов - агента - тот кто шлет сообщения, брокера - кто принимает и обрабатывает - и собственно класса выполняющего действия. Но у меня задача немного другая - синхронизация N-окон между собой и своевременное их обновление. В твоем случае возможно более простое решение. Когда я жене ваял чтото типа программы кроя - то сначала пошел по твоему пути - рисовал канву заново при каждом событии и программа тормозила жутко, пока я не допер что не обязательно рисовать все каждый раз заново...:)
Кстати, посмотри в исходниках того же Image.
...
Окошко плавает, все рисуется. Данные при этом (т.е. сам график) берутся из базы данных. Сейчас я при каждой перерисовке (а она, естественно, происходит и при изменении размеров окна, и при его перемещении) открываю запрос и в цикле читаю данные и строю графики:
...
А был вроде TDBChart - не подходит?
Тогда:
1. При перерисовке данные читать точно не надо (это будет супер непроизводительно).
2. Картинку готовить в памяти, а потом переносить на форму.