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

Вниз

Вопрос о временный таблицах   Найти похожие ветки 

 
Officeman   (2006-05-16 00:52) [0]

Уважаемые господа!
Нужно быстро создавать (временную) табличку на 10"000 столбцов.

В начале проекта использовал TListView и генерировал таблички от 100 до 1000 столбцов этого вполне хватало. но с увеличением числа столбцов до 10"000. Обработка добавления столбцов сильно тормозила, время на обработку до 10 часов. ))))).
Конечно это не выход! )  Что можете посоветовать?

Требования:
1) Хранение всей таблицы в памяти(получение значения из любой ячейки, по аналогии использования TListView)
2) Возможность организации цикла по табличке.

Интересуют все возможные(известные) методы в ДЕлфи

с Уважением, Officeman


 
Джо ©   (2006-05-16 00:59) [1]

array.


 
Palladin ©   (2006-05-16 09:15) [2]

или TList
+ работа TListView в виртуальном режиме


 
Jeer ©   (2006-05-16 09:26) [3]

Officeman   (16.05.06 00:52)

Или один из вариантов СУБД с поддержкой "Table in memory"


 
Сергей М. ©   (2006-05-16 09:47) [4]

Какое макс. кол-во записей планируется хранить в такой таблице ?


 
Officeman   (2006-05-16 10:02) [5]

2Сергей М., записей порядка 200, не больше.
коооличество столбцов 10"000, возможно нужно будет больше.

p.s.
вчера формировал табличку на 10"000, используя мощный ПК, формировалось 5 часов. немыслемо долго.

2Palladin
"или TList + работа TListView в виртуальном режиме"
хм. TList попробую сегодня.


 
Сергей М. ©   (2006-05-16 10:12) [6]

Данные какого типа должны храниться в таблице ?


 
Jeer ©   (2006-05-16 12:30) [7]

Officeman   (16.05.06 10:02) [5]

А верна ли постановка задачи ?

> вчера формировал табличку на 10"000, используя мощный ПК,
>  формировалось 5 часов. немыслемо долго.


 
Desdechado ©   (2006-05-16 12:49) [8]

> записей порядка 200, не больше.
> столбцов 10"000, возможно нужно будет больше.
а не приходило в голову повернуть таблицу на 90 градусов?
тогда столбцов не более 200, а строк - сколько втиснешь


 
TUser ©   (2006-05-16 14:31) [9]

Верно ли, что таблица должна быть на экране, или достаточно двухмерного массива в памяти? Есть подозрение, что тормоза возникают из-за прорисовки.


 
Jeer ©   (2006-05-16 16:33) [10]


> таблица должна быть на экране


Очень плохо представляю на экране таблицу с 10 тыс строк или столбцов.


 
TUser ©   (2006-05-16 16:44) [11]


> Очень плохо представляю на экране таблицу с 10 тыс строк
> или столбцов.

Бегунок справа/снизу.


 
Jeer ©   (2006-05-16 17:14) [12]

TUser ©   (16.05.06 16:44) [11]

Все равно не получается:))

Через пару сотен записей забываю предыдущие.


 
Palladin ©   (2006-05-16 17:14) [13]

:) мда... тут что то не так... столбцов так 20 - это уже расстройство желудка... но 10 тыс.... это по настоящему страшно... попробовал ради интереса хотя бы тысячу добавить в TListView, просто, без данных Columns.Add... на celeron 2.8 с LockWindowUpdate 2.7 минуты...


 
Officeman   (2006-05-17 08:54) [14]

Приветствую всех вас!
Спасибо за поддержку топа!

1) табличку выводить на экран не надо.
2) данные integer.
3) развернуть табличку можно но придётся в корне менять движок, много времени займёт.

p.s. как я уже понял TListView не вариант для 10"000 столбиков ))).  
пробовал TListItem, не понял как организовать цикл добавления столбцов(


 
Сергей М. ©   (2006-05-17 09:00) [15]


> Officeman   (17.05.06 08:54) [14]


п.1 в сочетании с п.2 однозначно говорят об изначально неверном выборе TListView в кач-ве контрола, эффективно решающего задачу


 
evvcom ©   (2006-05-17 09:41) [16]

Может лучше задачу озвучишь, чем спрашивать о быстроте создания 10000 столбцов?


 
Officeman   (2006-05-17 10:24) [17]

Окей!

Задача: принажатии на кнопочку, создать табличку заданного размера
X x Y(число столбцов на число позиций), с последующей возможностью работы с ячейками этой таблицы., аналогично TListView. Пример действий: из таблицы получить данные всей строки, столбца или данные конкретной ячейки(x,y). т.е. организация цикла по табличке.

данные типа integer, заносятся в табличку в момент её создания.


 
ЮЮ ©   (2006-05-17 10:36) [18]

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

И какие это возможности, кроме редактироования первого столбца?

a: Array of Array of <нужный тип>
SetLength(a, <число строк>, <число столбцов>

Визуализация:
1) TListView  в виртуальном режиме (OwnerData = true)
2) TDrawGrid - получишь доступ к каждой ячейке, а не строке целиком


 
Сергей М. ©   (2006-05-17 10:36) [19]


> Officeman   (17.05.06 10:24) [17]


И чем использование обычного двумерного массива тебе не угодило ?

Куда уж проще и быстрей - объявил такой массив, создал-заполнил его и шаришься по нему как твоей душе угодно ..


 
Officeman   (2006-05-17 11:09) [20]

to ЮЮ,  только заполнение в процессе создания. во время последующего использования - только читать данные.

//TListView  в виртуальном режиме (OwnerData = true)
попробую. хотя никогда не использовал. будут вопросы - спрошу.

to Сергей М.
сложность в послед.обработке данных.

спасибо.


 
Сергей М. ©   (2006-05-17 11:23) [21]


> Officeman   (17.05.06 11:09) [20]


> сложность в послед.обработке данных


В чем же она состоит ?
Проиллюстрируй ..


 
Officeman   (2006-05-17 11:47) [22]

при каждом нажатии кнопки обрабатывается следующая строка таблицы,
с циклом по всем столбикам. (с определённым условием)

Каждый столбик имеет свой порядковый номер записанный в Caption. указав номер столбца - можно получить все его значения (в столбик).

т.е. нужна возможность организованного цикла по строкам или столбцам таблички.


 
Сергей М. ©   (2006-05-17 11:55) [23]


> порядковый номер записанный в Caption


Зачем что-то записывать в Caption, если по условию


> 1) табличку выводить на экран не надо


?

Зачем вообще хранить целое число в строковом представлении, если для этого существует Integer-тип ?


> указав номер столбца - можно получить все его значения


Ну так в случае с массивом все это как раз замечательно решается !
В чем проблема-то ?


 
MetalFan ©   (2006-05-17 12:08) [24]

народ, мастера, вы что, прикалываетесь?!
зачем визуальные компоненты использовать в невидимом режиме для хранения данных?!
чем вам динамические массивы не подходят?
или какой-нить TMemoryTable из RX или JVCL


 
Jeer ©   (2006-05-17 12:08) [25]


> В чем проблема-то ?


Вероятно, от незнания основ программирования и элементарных структур данных.


 
Сергей М. ©   (2006-05-17 12:14) [26]

const

 MaxRows = 200;
 MaxCols = 10000;

type

 PTempTable = ^TTempTable
 TTempTable = array[0..MaxRows-1, 0..MaxCols-1] of Integer;
 PTempRow = ^TTempRow;
 TTempRow = array[0..MaxCols-1] of Integer;
 PTempCol = ^TTempCol;
 TTempCol = array[0..MaxRows-1] of Integer;

var
 TempTable: PTempTable;
 TempRow: PTempRow;
 TempCol: PTempCol;
 Rows: Integer = MaxRows;
 lCols: Integer = MaxCols;
 Row, Col: Integer;
 i: Integer;
..
 
 i := 0;
//создаем таблицу
 GetMem(TempTable, Rows * Cols * SizeOf(Integer));
 try
//инициализируем таблицу
    for Row := 0 to Rows - 1 do
      for Col := 0 to Cols - 1 do begin
        TempTable[Row, Col] := i;
        Inc(i);
      end;

//получаем содержимое 3-го столбца
 GetMem(TempCol, Rows * SizeOf(Integer));
 try
   Col := 3;
   for Row := 0 to Rows - 1 do
     TempCol[Row] := TempTable[Row, Col];
   ....
 finally
   FreeMem(TempCol);
 end;

//получаем содержимое 5-й строки
 GetMem(TempRow, Cols * SizeOf(Integer));
 try
   Row := 5;
   for Col := 0 to Cols - 1 do
     TempRow[Col] := TempTable[Row, Col];
   ....
 finally
   FreeMem(TempRow);
 end;

 finally
//уничтожаем таблицу
   FreeMem(TempTable);
 end;


 
Officeman   (2006-05-17 13:52) [27]

На первых стадиях проекта, нужно было видеть все данные.
для анализа и совершенствования алгоритма. математич.модель.
табличка предполагалась 100 столбцов на 100 позиций.
Прошло 4 месяца) запросы возросли и появилась необходимость изменить программу)

p.s.
я больше математик, нежели программист.
спасибо за инстуктаж. примеры ооочень пригодятся


 
Сергей М. ©   (2006-05-17 14:04) [28]


> На первых стадиях проекта, нужно было видеть все данные.


Их и сейчас, при использовании массива, можно "увидеть", причем без особых потуг.

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


 
Officeman   (2006-05-17 15:58) [29]

т.е. ты хочешь сказать что можно также использовать TListView но переключив его в виртуальный режим? тогда вопрос: код добавления столбцов и строк, надо менять? щас буду мучать OwnerData )


 
Сергей М. ©   (2006-05-17 16:02) [30]


> код добавления столбцов и строк, надо менять?


Его, этого кода, вообще не будет в вирт.режиме.


 
TStas ©   (2006-05-17 19:18) [31]

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


 
Джо ©   (2006-05-17 19:23) [32]

> А чем плохо хранить данные в динамическом массиве

Да ничем не плохо. Вроде, тут каждый второй пост именно об этом.


 
Officeman   (2006-05-18 07:41) [33]

2Сергей М.  посоветуй источник информации по этому вопросу [30]
p.s.
) когда включаю режим  OwnerData=true,  процесс создания таблы, заметно увеличивается. каким макаром потом устроить цикл по табличке?

спасибо.


 
Officeman   (2006-05-18 08:03) [34]

а если использовать всё таки массив данных. на примере описанном в посте [26]
каким образом правильно выделить память. попробовал текущий код. до удачного завершения обработки - система "вешается",  w2000 например. после завершения операции - ос отпадает и нормально пашет.


 
Сергей М. ©   (2006-05-18 08:11) [35]


> Officeman   (18.05.06 07:41) [33]


см. стандартную справку и демо-проект

(%Delphi7%)\Demos\Virtual Listview


> включаю режим  OwnerData=true,  процесс создания таблы,
> заметно увеличивается


Создание таблицы в массиве не имеет отношения к ListView - последний лишь отображает содержимое заранее подготовленной таблицы.


> каким макаром потом устроить цикл по табличке?


Ты в [26] пример разобрал ? Там как раз и фигурирует "цикл по табличке" (см. комментарий //создаем таблицу)


 
Jeer ©   (2006-05-18 11:04) [36]


> Officeman   (18.05.06 08:03) [34]


Совершенно непонятно почему Вас не устраивает просто:

const
ColMax = 200;
RowMax = 200;

var
arTable: array of array of integer;

// Выделение памяти
SetLength(arTable,  RowMax, ColMax);

// Обращение к элементу
arTable[i,j];

Окно просмотра задаете нужного (разумного) размера и выводите в любой визуальный Grid.


 
Сергей М. ©   (2006-05-18 11:10) [37]


> Officeman   (18.05.06 08:03) [34]
> каким образом правильно выделить память.


А в примере разве не правильно ?
Какие сомнения у тебя возникли по этому поводу ?


> попробовал текущий
> код. до удачного завершения обработки - система "вешается",
>   w2000 например. после завершения операции - ос отпадает
> и нормально пашет.


Что есть "система "вешается" ? Форма не реагирует на клаву/мышь  что ли ?


 
Officeman   (2006-05-18 11:47) [38]

Спасибо за подробные ответы. Очень признателен.

>to Jeer
>const
>ColMax = 200;
>RowMax = 200;


да. опыта мне нехватает. (
НУжно сделать так чтобы пользователь сам выбирал
размеры таблицы используя  Edit1, Edit2
перед её созданием., а тут жёстко задаётсяконстантами.
подскажите как правильно это сделать. спасибо.

>А в примере разве не правильно ?
>Какие сомнения у тебя возникли по этому поводу ?


нужно создать более одной таблицы. и держать их в памяти.
с возможностью работы с ними(получение данных).
во время работы программы.
Одна табличка на 10"000 стоблцов  x 200 строк
Вторая и Третья таблички, по 10"000 столбцов на 4 строки.

>Что есть "система "вешается" ? Форма не реагирует на клаву/мышь  что ли ?

не только форма. но и ОС тоже. сильно тормозит на секунд 10. потом отвисает и через некоторые время снова повторяется завис. - всё это происходит во время работы  обработки.   ОЗУ 512.   да вобщем это неглавное.


 
Сергей М. ©   (2006-05-18 12:00) [39]


> Officeman   (18.05.06 11:47) [38]


Почему же константами ?
Переменными !

Rows: Integer = MaxRows; //по умолчанию - максимально возможное число строк
Cols: Integer = MaxCols; //по умолчанию - максимально возможное число столбцов

Перед тем как создавать таблицу ты волен изменить значения переменных Rows и Cols, взяв их из тех самых Edit"ов


> нужно создать более одной таблицы. и держать их в памяти


В чем же проблема ?


 
Сергей М. ©   (2006-05-18 12:04) [40]


> всё это происходит во время работы  обработки


Что подразумевается под "обработкой" ?
Иллюстрируй в коде ..


 
Officeman   (2006-05-18 12:05) [41]

>В чем же проблема ?

не знаю как задать другое имя для временной таблички. (.
если не трудно (я всех достал, я знаю), приведи пример который ты уже приводил. но на 2 temp табличке.


 
Сергей М. ©   (2006-05-18 12:14) [42]

А что ты под "именем таблички" подразумеваешь ?
В моем примере у таблиц нет имен ..


 
ЮЮ ©   (2006-05-18 12:15) [43]

>не знаю как задать другое имя

var
 first, second, current: <когда с типом например определишься>;
 first и second создаешь и инициализируешь. Отрисовываешь и просчитываешь current, при переключении установив current := first (second)

второй вариант:

var
 tab: array of  <когда с типом например определишься>;
 Idx: integer;

 Отрисовываешь и просчитываешь tab[Idx]. Переключаешься изменением Idx


 
Jeer ©   (2006-05-18 12:26) [44]

Officeman   (18.05.06 12:05) [41]

В общем, начни с чтения умных книжек.


 
Сергей М. ©   (2006-05-18 13:02) [45]

const

MaxRows = 200;
MaxCols = 10000;

type

PTempTable = ^TTempTable
TTempTable = array[0..MaxRows-1, 0..MaxCols-1] of Integer;

PTempRow = ^TTempRow;
TTempRow = array[0..MaxCols-1] of Integer;

PTempCol = ^TTempCol;
TTempCol = array[0..MaxRows-1] of Integer;

PTempTableInfo = ^TTempTableInfo;
TTempTableInfo = packed record
  Rows, Cols: Integer;
  TableData: PTempTable;
end;

var
 TableList: TList;

...
 TableList := TList.Create;
...

function CreateTable(const Rows, Cols: Integer): Integer;
var
 Info: PTempTableInfo;
begin
 New(Info);
 try
   Info.Rows := Rows;
   Info.Cols := Cols;
   GetMem(Info.TableData, Rows * Cols * SizeOf(Integer));
   try
     InitTable(Info.TableData);
     Result := TableList.Add(Info);
   except
     FreeMem(Info.TableData);
     raise;
   end;      
 except
   Dispose(Info);
   raise;
 end;
end;

procedure DestroyTable(const Index: Integer);
var
 Info: PTempTableInfo;
begin
 Info := TableList[i];
 FreeMem(Info.TableData);
 Dispose(Info);
 TableList.Delete(i);
end;

procedure DestroyTableList;
var
 i: Integer;
begin
 for i := 0 to TableList.Count - 1 do DestroyTable(TableList[i]);
 TableList.Free;
end;

...

//пример обращения к элементу 3-й таблицы

PTempTable(TabeleList[2])[5, 6] := ...


 
Officeman   (2006-05-18 13:02) [46]

to ЮЮ, погодите плиз. ещё раз. я тех кто в танке. )
Помогите разобратся! Вы потрясающие учителя.



unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Mask, ToolEdit, CurrEdit;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   name34: TButton;
   Num: TRxCalcEdit;
   Memo2: TMemo;
   Memo3: TMemo;
   Button2: TButton;
   Num2: TRxCalcEdit;
   procedure Button1Click(Sender: TObject);
   procedure name34Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 const
MaxRows = 5000;    //колонок
MaxCols = 100;            //строк

type
PTempTable = ^TTempTable;    //  ??? такого в F1 вапще нет

TTempTable = array[0..MaxRows-1, 0..MaxCols-1] of Integer;
PTempRow = ^TTempRow;
TTempRow = array[0..MaxCols-1] of Integer;
PTempCol = ^TTempCol;
TTempCol = array[0..MaxRows-1] of Integer;

var
Form1: TForm1;
TempTable: PTempTable;   //  "TempTable"  это и есть имя таблички ?
TempRow: PTempRow;
TempCol: PTempCol;
Rows: Integer = MaxRows;
Cols: Integer = MaxCols;
Row, Col: Integer;
i: Integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

memo1.Visible:=false;
memo1.Clear;
memo2.Clear;

 Rows:= 100;
 Cols:= 20;

// создаём табличку под инедификатором  "TempTable"   ???????????
GetMem(TempTable, Rows * Cols * SizeOf(Integer));  

//заполняем значениями
   for Row := 0 to Rows-1 do //столбец
     for Col := 0 to Cols - 1 do begin //строка
      i := random(3);
      TempTable[Row, Col] := i;
      Inc(i);
      memo1.Lines.Add(inttostr(Row)+". "+inttostr(i));
     end;
  FreeMem(TempCol);
memo1.Visible:=true;
 end;

procedure TForm1.name34Click(Sender: TObject);
begin

Col := 3        

//штудируем все колонки, начиная с нулевой, получаем значения СТРОКИ 3
  for Row := 0 to Rows-2 do begin
    memo2.Lines.Add(inttostr(Col+1)+". "+inttostr(TempTable[row, col]+1));

//вот тут вапще косяк. в табличке записано 2,1,3. когда вытаскиваю.
//то получаю 1,0,2.  ровно на единицу меньше. пришлось приписать +1
//голову сломал, ответа не нашёл.


  end;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin

Row := 3   // значения текущей колонки !!!!!!!!!!!

//штудируем все Строчки, начиная с нулевой.
  for Col := 0 to Cols-1 do begin

// тоже самое +1 пришлось делать. чтобы правильные значения взять.
//я чёто неправильно сделал! непонимаю в чём гвоздь


    memo3.Lines.Add(inttostr(Row)+". "+inttostr(TempTable[row, col]+1));

  end;

end;

end.



 
Officeman   (2006-05-18 13:09) [47]

>//пример обращения к элементу 3-й таблицы
>PTempTable(TabeleList[2])[5, 6] := ...


т.е. ты создаёшь список из нескольких(трёх) таблиц?     [0,1,2]   так ?


 
Сергей М. ©   (2006-05-18 13:21) [48]


> Officeman   (18.05.06 13:09) [47]


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

Сколько раз ты вызовешь ф-цию Createtable, столько таблиц и будет создано.

В строчке

PTempTable(TabeleList[2])[5, 6] := ...

подразумевается, что Createtable() была вызвана тобой не менее 3-х раз


 
Сергей М. ©   (2006-05-18 13:23) [49]


> TempTable: PTempTable;   //  "TempTable"  это и есть имя
> таблички ?


Это не "имя таблички", это символьный идентификатор переменной, предназначенной для хранения указателя на данные типа  TTempTable


 
Сергей М. ©   (2006-05-18 13:32) [50]

Наврал.

Вот так будет правильней :

procedure InitTable(const Table: PTempTableInfo);
var Row, Col: Integer;
begin
 with Info^ do
 for Row := 0 to Rows - 1 do
   for Col := 0 to Cols - 1 do
     TableData[Row, Col] := ...;
end;

function CreateTable(const Rows, Cols: Integer): Integer;
var
Info: PTempTableInfo;
begin
New(Info);
try
  Info.Rows := Rows;
  Info.Cols := Cols;
  GetMem(Info.TableData, Rows * Cols * SizeOf(Integer));
  try
    InitTable(Info);
    Result := TableList.Add(Info);
  except
    FreeMem(Info.TableData);
    raise;
  end;      
except
  Dispose(Info);
  raise;
end;
end;


 
Officeman   (2006-05-18 14:08) [51]

Спасибо за краткий экскурс. если приду в очередной тупик подниму здесь вопросик. спасибо.


 
Officeman   (2006-05-19 09:18) [52]


Result := TableList.Add(Info);


как правильно инициализировать  TableList  , в этом случае


 
Сергей М. ©   (2006-05-19 09:24) [53]

Инициализация происходит строчкой выше:

InitTable(Info);



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

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

Наверх




Память: 0.62 MB
Время: 0.035 c
2-1149668742
SLP
2006-06-07 12:25
2006.06.25
insert


3-1146119582
vishnia
2006-04-27 10:33
2006.06.25
Использование метода TADOTable.Seek


2-1149772292
ALe_x
2006-06-08 17:11
2006.06.25
размер файла


2-1149680738
logslava
2006-06-07 15:45
2006.06.25
Картинка для SpeedButton


2-1149476015
kolbasa
2006-06-05 06:53
2006.06.25
Выборка из таблицы