Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.013 c
1-1147986841
Германн
2006-05-19 01:14
2006.06.25
Установка Indy9 на Д6


4-1142613185
AndreyRus
2006-03-17 19:33
2006.06.25
Аналог IOCTL_SCSI_RESCAN_BUS в Windows 2003


15-1148497229
Kerk
2006-05-24 23:00
2006.06.25
00:00


2-1149773285
Zikmu
2006-06-08 17:28
2006.06.25
Нумерация строк


2-1149735956
Need Help
2006-06-08 07:05
2006.06.25
Нужна помощь в алгоритме





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский