Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.19;
Скачать: CL | DM;

Вниз

Array ==> Tdataset   Найти похожие ветки 

 
SergP ©   (2006-01-15 15:53) [0]

Имеется array of record
Количество элементов массива порядка 50000 - 100000
Ножно отобразить его для просмотра пользователем.
Проблема в том что когда пытаюсь запихнуть все данные массива целиком в TListView программа очень долго тормозит (я ждал несколько минут, но так и не дождался результата). В принципе почему - понятно.
Но тем не менее хочется все-таки решить эту проблему. (Именно отображения массива целиком, а не частями).
поэтому вопрос: Можно ли как-нить написать некий класс (типа TDataset) чтобы объект этого класса брал данные не из базы данных, а из массива, чтобы потом можно было отобразить нужную информацию в TDBGrid?
Хочу таким образом поступить из-за того что DBGrid будет брать только те данные которые он сможет отобразить в "видимой его части", и по идее тормозить не должен.
Делал ли кто нечто подобное? Поделитесь соображениями...


 
begin...end ©   (2006-01-15 15:56) [1]

> SergP ©   (15.01.06 15:53)

> Проблема в том что когда пытаюсь запихнуть все данные массива
> целиком в TListView программа очень долго тормозит (я ждал
> несколько минут, но так и не дождался результата). В принципе
> почему - понятно.
> Но тем не менее хочется все-таки решить эту проблему.

Виртуальный ListView использовать.


 
SergP ©   (2006-01-15 16:00) [2]


> Виртуальный ListView использовать.


Где его брать? Пожалуйста дайте ссылочку или хотя-бы фразу по которой искать...


 
begin...end ©   (2006-01-15 16:09) [3]

> SergP ©   (15.01.06 16:00) [2]

> Где его брать?

На вкладке Win32. Это обычный TListView, со свойством OwnerData = True.

Устанавливаете нужное значение ListView.Items.Count, а в обработчике OnData формируете элементы.


 
sniknik ©   (2006-01-15 16:40) [4]

> Имеется array of record
> Количество элементов массива порядка 50000 - 100000
... размер предполагает уже чтото типа базы использовать. либо как минимум отдельный рекордсет (клиентскмий/ado-шный), любой который можно сохранять в файл. (+ рекордсета в том что он позволяет поиск/индексы/фильтры на таком обьеме не лишнее будет)

> Можно ли как-нить написать некий класс (типа TDataset)
не проблема.
пример
x:\Program Files\Borland\Delphi7\Demos\Db\TextData\*.*
потребуются совсем небольшие изменения.


 
begin...end ©   (2006-01-15 16:48) [5]

> sniknik ©   (15.01.06 16:40) [4]

> размер предполагает уже чтото типа базы использовать.

Размер (сам по себе) не может этого предполагать. В [0] названа только одна причина возникновения идеи о БД: "Хочу таким образом поступить из-за того что DBGrid будет брать только те данные которые он сможет отобразить в "видимой его части", и по идее тормозить не должен." Т.к. о поиске, сохранении в файл и т.д. речи не идёт, поставленная задача легко решается без БД.


 
Alex Konshin ©   (2006-01-15 16:55) [6]

Можешь попробовать мой ArrayGrid. Может и понравится. Смотри в анкете.


 
SergP ©   (2006-01-15 16:57) [7]


> sniknik ©   (15.01.06 16:40) [4]
> > Имеется array of record
> > Количество элементов массива порядка 50000 - 100000
> ... размер предполагает уже чтото типа базы использовать.
>  либо как минимум отдельный рекордсет (клиентскмий/ado-шный),
>  любой который можно сохранять в файл. (+ рекордсета в том
> что он позволяет поиск/индексы/фильтры на таком обьеме не
> лишнее будет)


Конечно с базой было бы удобнее, но не хочется цеплять к сравнительно небольшому приложению, какую-нить СУБД, в данном случае это будет неоправданным увеличением размеров, тем более если учесть, что
сама запись небольшая:


type
 RateRecord = record
   rDate:TDateTime;
   rValute: array[0..3] of Single;
 end;


да и массив изначально является отсортированням по rData, а по остальным полям сортировка не требуется. Поиск тоже будет производиться по rData. А в отсортированном массиве я лучше применю бинарный поиск чем буду использовать БД с индексами...

Вобщем попробую:

> begin...end ©   (15.01.06 16:09) [3]


Если вдруг не устроит, буду смотреть:

> sniknik ©   (15.01.06 16:40) [4]
> x:\Program Files\Borland\Delphi7\Demos\Db\TextData\*.*


Спасибо всем!


 
SergP ©   (2006-01-15 17:16) [8]


> Alex Konshin ©   (15.01.06 16:55) [6]
> Можешь попробовать мой ArrayGrid. Может и понравится. Смотри
> в анкете.


На всякий случай и это тоже закачал... Надеюсь под Д6 оно станет? А то у Вас написано что Д4....


 
sniknik ©   (2006-01-15 17:17) [9]

> тем более если учесть, что
> сама запись небольшая:
> ...
сохраненное в формате pfADTG (ниже) будет занимать не намного больше места чем у тебя сейчас.

> Конечно с базой было бы удобнее, но не хочется цеплять к сравнительно небольшому приложению, какую-нить СУБД
и не потребуется, возьми ADORecordSet (ADO есть практически везде даже устанавливать не придется) и используй отдельно от баз. (SaveTo/LoadFromFile форматы pfADTG, pfXML, либо тоже с типом команды cmdFile, указываеш в комманд техт файл... и Open/Close)
и все. база не нужна. правда и запросов не поделаеш... к такой отдельностоящей таблице. но плюсов все одно больше.


 
atruhin ©   (2006-01-15 17:19) [10]

> sniknik ©   (15.01.06 16:40) [4]
> x:\Program Files\Borland\Delphi7\Demos\Db\TextData\*.*
сильно не смотри, очень примитивный пример и практически не работоспособный, в реальных приложениях.
Есть масса компоненотв типа MemoryTable, выбери нужный или смотри их.


 
sniknik ©   (2006-01-15 17:32) [11]

> Надеюсь под Д6 оно станет? А то у Вас написано что Д4....
тестил и под D7 вставало, вполне прилично кстати (по скорости очень даже. недостаток только в том что при повторной сортировке занимает тоже время что и при первой... т.к. сортировка записей физическая (в отличие от построения индекса в рекордсете, где первый раз индекс строится дольше, а при повторном использовании время стремится к нулю), впрочем если не предполагается частых переключений сортировок то это можно считать достоинством т.к. первая сортировка всетаки быстрее рекордсетного)

atruhin ©   (15.01.06 17:19) [10]
> сильно не смотри, очень примитивный пример и практически не работоспособный, в реальных приложениях.
не рви из контекста, это ответ на вопрос
> Можно ли как-нить написать некий класс (типа TDataset)
и потом каким еще должен быть пример? навороченным настолько чтобы только разработчик мог в нем разобратся?
как пример он очень хорош.

> Есть масса компоненотв типа MemoryTable, выбери нужный или смотри их.
приведенные рядом клиентскмий/ado-шный рекордсеты одни из них, только стандартные и в поставке дельфей.


 
sniknik ©   (2006-01-15 17:45) [12]

> тестил и под D7 вставало, вполне прилично кстати ...
да забыл... тогда тетил толи на 3 толи на 5 милионах записей (в обшем на много ;), на 100 тысячах тебе будет пофигу время повторной сортировки... т.к. ты ни первую ни повторную даже не заметиш, если только специально не засечеш програмным способом (либо машина ну очень тормозная ;).


 
SergP ©   (2006-01-15 18:00) [13]


> сохраненное в формате pfADTG (ниже) будет занимать не намного
> больше места чем у тебя сейчас.


Не знаю... Если имеется ввиду место на диске, то не уверен...
У меня на данный момент длина масива 30830, длина записи 24 байта.
Итого 739920 байт...

Я сохраняю массив в файл таким образом (с компрессией):

procedure RateSave;
var
 fstream:TFileStream;
 tempsize:integer;
begin
 fStream:=TFileStream.Create("Rates.dat",fmCreate);
 try
   with TCompressionStream.Create(clMax,fstream) do
     try
       tempsize:=length(aRate);
       WriteBuffer(tempsize,sizeof(tempsize));
       WriteBuffer(aRate[0],length(aRate)*sizeof(aRate[0]));
     finally
       Free;
     end;
 finally
   fstream.free;
 end;
end;


Получаю файл размером 296241 (конечно, здесь размер может меняться в зависимости от самих данных, но не очень).
Единственная проблема такого способа - компрессия данных выполняется в заметное пользователю время (на данный момент около 2 сек на Athlon 1000), но я думаю еще ужать размер записи.
Например дату можно поместить в Cardinal, так как точность нужна только до секунд, насчет остальных 4 чисел (array[0..3] of single) данных, то им вполне хватит по 3 байта (даже возможно и по 2), а не по 4(single), тут проблема только в том что в Дельфи нет вещественных (или в крайнем случае целых) чисел размером 3 байта, а реализовывать самому преобразование данных к такому формату (своему формату вещественных трехбайтовых чисел) и обратно не особо хочется.


 
atruhin ©   (2006-01-15 18:07) [14]

>>и потом каким еще должен быть пример? как пример он очень хорош.
Несогласен. Был бы хорош, если бы остальное было бы описано хотя бы в хелпе. Но dataset не описан вообще нигде, по крайней мере из того что я видел, лучшее Тейксейра, Паченко, но даже там нет и 50% необхлдимой информации для написания полноценного потомка TDataset.
Борланд отсылает к исходным текстам, если вы сталкивались с этим, должны знать. На основе данного примера нельзя сделать ничего более, менее работающего.


 
atruhin ©   (2006-01-15 18:12) [15]

>> (на данный момент около 2 сек на Athlon 1000
что то не то, в вашей консерватории, :) 1 мб не может записываться на HDD около 2 сек.


 
SergP ©   (2006-01-15 18:22) [16]


> atruhin ©   (15.01.06 18:12) [15]
> >> (на данный момент около 2 сек на Athlon 1000
> что то не то, в вашей консерватории, :) 1 мб не может записываться
> на HDD около 2 сек.


так ведь перед записью происходит компрессия ZLIB. В основном время на нее тратится... Хотя декомпрессия происходит почти моментально (на глаз не заметно)


 
atruhin ©   (2006-01-15 18:26) [17]

>>так ведь перед записью происходит компрессия ZLIB.
А зачем она нужна? Неужели на современнх дисках есть разница 200кб или 1 mb?


 
sniknik ©   (2006-01-15 18:45) [18]

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


 
Alex Konshin ©   (2006-01-16 10:17) [19]

> sniknik ©   (15.01.06 17:32) [11]
> > Надеюсь под Д6 оно станет? А то у Вас написано что Д4.
> ...
> тестил и под D7 вставало, вполне прилично кстати (по скорости
> очень даже. недостаток только в том что при повторной сортировке
> занимает тоже время что и при первой... т.к. сортировка
> записей физическая (в отличие от построения индекса в рекордсете,
>  где первый раз индекс строится дольше, а при повторном
> использовании время стремится к нулю), впрочем если не предполагается
> частых переключений сортировок то это можно считать достоинством
> т.к. первая сортировка всетаки быстрее рекордсетного)

Ты не прав, там никогда не делается физическая сортировка, а именно строится индекс. У меня в основе этого лежит свои динамические массивы. Можешь проверить, физически записи всегда остаются на месте и даже можно всегда "восстановить" первначальный порядок простым отключением сортировки. Кстати, там поддерживается не только сортировка, но и фильтрация, т.е. логически записей может быть меньше, чем физически. И можно обратиться к записям и по логическому индексу, и по физическому. По сути, эти массивы и есть самые, что ни на есть рекордсеты.


 
evvcom ©   (2006-01-16 10:47) [20]


> чисел размером 3 байта, а реализовывать самому преобразование
> данных к такому формату (своему формату вещественных трехбайтовых
> чисел) и обратно не особо хочется

И не надо этого делать, а то получишь еще дополнительные тормоза всего-то на мегабайте! У тебя чего там "Искра" стоит чтоль? :)


 
sniknik ©   (2006-01-16 11:00) [21]

Alex Konshin ©   (16.01.06 10:17) [19]
тогда у тебя глюк в реализации, я же судил по тому что у меня повторная сортировка заняла тоже самое время что первая. либо "индекс" поддерживается только один...
в исходники не лазил, чисто по поведению в примере. (получилось ошибочно судя по всему [19]. теперь думаю, что индекс только один)

пробовал так (аналогично тому что в рекордсете. с ним же сравнивал) сортировка по первому полю - время 12 сек, следом по второму/третьему - время 8 сек, возращаемся к сортировке первого - время опять 12 сек (+- какието дроби). в рекордсете ткойже повтор время - 0 сек. (+ какието дроби)


 
sniknik ©   (2006-01-16 11:03) [22]

> такойже повтор время - 0 сек. (+ какието дроби)
но изначальная (первая) зато гдето 20 сек. на аналогичных данных, размере.


 
Alex Konshin ©   (2006-01-17 14:01) [23]


> sniknik ©   (16.01.06 11:00) [21]
>
> Alex Konshin ©   (16.01.06 10:17) [19]
> тогда у тебя глюк в реализации, я же судил по тому что у
> меня повторная сортировка заняла тоже самое время что первая.
>  либо "индекс" поддерживается только один...
> в исходники не лазил, чисто по поведению в примере. (получилось
> ошибочно судя по всему [19]. теперь думаю, что индекс только
> один)
>
> пробовал так (аналогично тому что в рекордсете. с ним же
> сравнивал) сортировка по первому полю - время 12 сек, следом
> по второму/третьему - время 8 сек, возращаемся к сортировке
> первого - время опять 12 сек (+- какието дроби). в рекордсете
> ткойже повтор время - 0 сек. (+ какието дроби)


Ну да, индекс только один. А нафига их хранить? Если это так нужно, то можно и сделать, только писать по-больше придется.
Собственно в моем гриде скорость работы на больших объемах не была целью, это просто получилось как побочный эффект, потому что сама реализация сортировки шустрая. По большому счету это всего лишь демонстрация технологии, и с умом и фантазией этот инструмент можно под разные случаи специально заточить.

Я считаю, что давать пользователю для просмотра результат более 1000 строк бесмысленно - он один черт их не сможет все расмотреть, а будет крутить его туда-сюда. Встроенная фильтрация и сортировка в моем гриде может существенно помочь, но все равно увеличивать кол-во строк - только напрягать базу, память и сеть, пользователю от этого удобней не будет. А на объемах в десятки тысяч строк сортировка работает мгновенно - нет смысла хранить какие-то индексы в надежде сэкономить на повторах.



Страницы: 1 вся ветка

Текущий архив: 2006.02.19;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.085 c
10-1113893671
e-not
2005-04-19 10:54
2006.02.19
Помогите разобраться с вызовом функции на COM-сервере


2-1138709886
Andrey235
2006-01-31 15:18
2006.02.19
Как узнать имя компонента


2-1138957015
саня_
2006-02-03 11:56
2006.02.19
Подскажите решение


2-1138716658
TimScorp
2006-01-31 17:10
2006.02.19
Формы


2-1138607660
De
2006-01-30 10:54
2006.02.19
поясните