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

Ваш аккаунт

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

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

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

Вопрос про TQuery

621
09 января 2005 года
Бешеный кролик
151 / / 23.03.2004
Делаю плавающие графики как в 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-й? Мож. кто-нибудь что-нибудь более остроумное предложит :)?
Заранее спасибо.
1.8K
10 января 2005 года
ALI
129 / / 10.01.2003
какая база локальная или SQL сервер??

а вообще количество соединенийс базой определятся не количеством открытых TQuery
а количеством созданных объектов TSession
те если у тебя один TDatabase и 100 TQuery
то если явно не указывать TSession все TQuery будут использовать одно и то же соединение...
1
10 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by Бешеный кролик
Сейчас я при каждой перерисовке (а она, естественно, происходит и при изменении размеров окна, и при его перемещении) открываю запрос и в цикле читаю данные и строю графики:

...
При этом есть две альтернативы:
...


Не очень понятно - зачем вызывать запросы при каждой перерисовке? Если предполагается динамическое обновление данных - имеет смысл обновлять данные по какому либо событию - самый простой - по таймеру, но лучше использовать оконные сообщения - т.е. пользователь изменил что либо в данных - посылается зарегистрированное тобой сообщение и только после этого данные перечитываются. Если же графики - статические, что кстати следует из твоего сообщения - смысла в этом нет никакого - если винда не может корректно отрисовать твое окно(почему то?) - отрисовуй его сам - но это в любом случае будет быстрее чем вычитка новых данных. Копирование картинки в оперативку и из нее пожалуй на несколько порядков будет быстрее чем выполнение даже небольшого запроса.
Вариант со списками менее накладен, если оперативки в достатке - но здесь лучше использовать динамические массивы - они более эффективны по скорости доступа, чем списки - ведь чтение у тебя все равно последовательное.

259
10 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by Бешеный кролик
Делаю плавающие графики как в 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 делать один раз, то тормоза не будет. В варианте со списком ты займешь гораздо больше ОЗУ. А это может привести к тормозу других приложений и к ненужному свопингу.

621
10 января 2005 года
Бешеный кролик
151 / / 23.03.2004
2 ALI База данных локальная, спасибо за информацию.

2 kot_ графики у меня действительно статические. Они в отдельных окошках, поэтому должны перерисовываться всякий раз при изменении размеров окна или его перемещении. Хранить картинку в оперативке, ИМХО, нездорово, т.к. возникнут некоторые проблемы с масштабированием особенно с масштабированием шрифтов и т.п. Запросы при каждой отрисовке сделал, т.к. делал в "первом приближении", теперь отлаживаю. Заменю по твоему совету в своей проге все списки на динамические массивы.

2AlexandrVSmirno Отлично!

Еще раз всем спасибо.
1
10 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by Бешеный кролик
Хранить картинку в оперативке, ИМХО, нездорово, т.к. возникнут некоторые проблемы с масштабированием особенно с масштабированием шрифтов и т.п.


Это все целиком зависит от того, что ты пытаешься сделать. Если горят сроки, лень, бесплатная работа, единственная задача этой программы - или еще какая причина - забей и делай как проще.
Но ни кто и не предлагает хранить картинку в оперативке - и кстати какие проблемы при этом собственно могут возникнуть?:D
По возможности стоит использовать механизмы ОС, а не придумывать велосипед себе же на ж.... Если система не велика - вариант с запросами сгодится под пиво. Если же планируешь(требуют) сделать качественную программу - без механизма сообщений тебе обойтись не получится и тогда отрисовка окон запросом+система массивов(списков) будет у тебя самым сильным тормозом из за которого прийдется переписать программу, где бы они не хранились, тем более, что чтение с диска - на сегодняшний день не самая быстрая из операций. А работа с базой как правило имеет тенденцию очень быстро перерастать из локальной в сетевую.

621
10 января 2005 года
Бешеный кролик
151 / / 23.03.2004
Цитата:
Originally posted by kot_

Это все целиком зависит от того, что ты пытаешься сделать. Если горят сроки, лень, бесплатная работа, единственная задача этой программы - или еще какая причина - забей и делай как проще.
Но ни кто и не предлагает хранить картинку в оперативке - и кстати какие проблемы при этом собственно могут возникнуть?:D
По возможности стоит использовать механизмы ОС, а не придумывать велосипед себе же на ж.... Если система не велика - вариант с запросами сгодится под пиво. Если же планируешь(требуют) сделать качественную программу - без механизма сообщений тебе обойтись не получится и тогда отрисовка окон запросом+система массивов(списков) будет у тебя самым сильным тормозом из за которого прийдется переписать программу, где бы они не хранились, тем более, что чтение с диска - на сегодняшний день не самая быстрая из операций. А работа с базой как правило имеет тенденцию очень быстро перерастать из локальной в сетевую.



Ты прав безусловно. Поэтому я и отказался от запросов при отрисовке (я и сделал-то так временно, чтобы побыстрее все заработало). Данные будут храниться либо в динамических массивах, либо я просто открою для каждого окошка n-ое количесво Query (т.е. выполню запросы один раз при создании графика) и при отрисовке буду читать данные. Посмотрю что быстрее. Подумаю насчет хранения картинки в оперативке, это заманчиво, но здесь у меня действительно возникают специфические проблемы: у меня при изменении размеров окна, меняется сетка, т.е. меняется количество линий сетки, шаг по оси ординат, временная шкала по оси абсцисс и т.п.
С уважением, Кролик :)

621
10 января 2005 года
Бешеный кролик
151 / / 23.03.2004
А может я тебя не понял просто?
Я в принципе графикой первый раз занимаюсь.
У меня в OnPaint каждый раз идет отрисовка графика. Если можно без этого обойтись, то как?
Кинь общую идею, а я уж гугле посмотрю подробности.
1
11 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by Бешеный кролик
А может я тебя не понял просто?
Я в принципе графикой первый раз занимаюсь.
У меня в OnPaint каждый раз идет отрисовка графика. Если можно без этого обойтись, то как?
Кинь общую идею, а я уж гугле посмотрю подробности.


Может и не понял - или я плохо объяснил. Дело в том, что график то у тебя нарисован при создании формы - и тебе не нужно рисовать его каждый раз заново - тебе достаточно его просто копировать. А реализовать это можно как минимум двумя способами -
Первый и самый простой - это использование Image:

 
Код:
Graphics::TBitmap *pBitmap = new Graphics::TBitmap();
 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.
246
11 января 2005 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by Бешеный кролик

...
Окошко плавает, все рисуется. Данные при этом (т.е. сам график) берутся из базы данных. Сейчас я при каждой перерисовке (а она, естественно, происходит и при изменении размеров окна, и при его перемещении) открываю запрос и в цикле читаю данные и строю графики:
...


А был вроде TDBChart - не подходит?
Тогда:
1. При перерисовке данные читать точно не надо (это будет супер непроизводительно).
2. Картинку готовить в памяти, а потом переносить на форму.

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