Конференция "Базы" » ClientDataSet as memtable - тормозит при добавлении записей [D7]
 
  • Alex_C (28.12.11 17:57) [0]
  • Виталий Панасенко (28.12.11 18:08) [1]
    своп
  • sniknik © (28.12.11 19:35) [2]
    > своп
    ???
    ну и нафига сейчас нужен комп с 64 мег оперативы "на борту"? выкинуть и сразу решатся все проблемы с тормозами...

    нет уж, тут что-то другое, я за "кривые руки". кто еще?...
  • Jeer © (28.12.11 21:01) [3]

    > потом начинает тормозить.


    Треба расшифровки - насколько, в количественном выражении.
  • Ega23 © (29.12.11 10:19) [4]
    ClientDataSet.DisableControls;
    try
     // Добавляем в него 100500 записей;
    finally
     ClientDataSet.EnableControls;
    end;  



    Так тоже тормозит?
  • Alex_C (29.12.11 10:40) [5]

    >  я за "кривые руки". кто еще?...


    ... Борланда? :)
    Пустой проект. Есть только ClientDataSet и VolgaTable.
    Цикл добавления. Более - ничего.
    Время добавления в VolgaTable - 35 тыс записей - около 23 сек. Причем при добавлении еще 35 - 30 сек. У ClientDataSet - 35 сек, еще 35 тыс - 1,5 мин.
  • Alex_C (29.12.11 10:41) [6]

    > Так тоже тормозит?


    Ну я все же не совсем идиот :) Конечно - да)))
  • sniknik © (29.12.11 10:56) [7]
    > Ну я все же не совсем идиот :) Конечно - да)))
    я про это всегда забываю... когда вижу голословные утверждения. нет ни капли желания проверять. проще верить интуиции про "кривые руки".
  • Ega23 © (29.12.11 13:09) [8]

    > Ну я все же не совсем идиот :) Конечно - да)))


    Ну вот прикола ради тест наваял:


    unit Unit30;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, DB, DBClient, StdCtrls;

    type
     TForm30 = class(TForm)
       btnInitCDS: TButton;
       CDS: TClientDataSet;
       btnAdd1000: TButton;
       btnAdd10000: TButton;
       btnAdd100000: TButton;
       lblResult: TLabel;
       btnAdd1000000: TButton;
       procedure btnInitCDSClick(Sender: TObject);
       procedure btnAdd1000Click(Sender: TObject);
       procedure btnAdd10000Click(Sender: TObject);
       procedure btnAdd100000Click(Sender: TObject);
       procedure btnAdd1000000Click(Sender: TObject);
     private
       procedure InitCDS;
       procedure AddNRecords(Value: Integer);
       procedure UpdateResultLabel(tc: Cardinal);
     public
       { Public declarations }
     end;

    var
     Form30: TForm30;

    implementation

    {$R *.dfm}

    { TForm30 }

    procedure TForm30.AddNRecords(Value: Integer);
    var
     tc: Cardinal;
     i: Integer;
    begin
     Screen.Cursor := crHourGlass;
     try
       tc := GetTickCount;
       try
         CDS.DisableControls;
         try
           for i := 1 to Value do
           begin
             CDS.Append;
             try
               CDS.FieldByName('ID').AsInteger := i;
               CDS.FieldByName('Caption').AsString := 'AAAA';
             finally
               CDS.Post;
             end;
           end;
         finally
           CDS.EnableControls;
         end;
       finally
         UpdateResultLabel(GetTickCount - tc);
       end;
     finally
       Screen.Cursor := crDefault;
     end;
    end;

    procedure TForm30.btnAdd1000000Click(Sender: TObject);
    begin
     AddNRecords(1000000);
    end;

    procedure TForm30.btnAdd100000Click(Sender: TObject);
    begin
     AddNRecords(100000);
    end;

    procedure TForm30.btnAdd10000Click(Sender: TObject);
    begin
     AddNRecords(10000);
    end;

    procedure TForm30.btnAdd1000Click(Sender: TObject);
    begin
     AddNRecords(1000);
    end;

    procedure TForm30.btnInitCDSClick(Sender: TObject);
    begin
     InitCDS;
    end;

    procedure TForm30.InitCDS;
    begin
     try
       if CDS.Active then
       begin
         CDS.EmptyDataSet;
         CDS.Close;
       end;

       CDS.FieldDefs.Clear;
       CDS.FieldDefs.Add('ID', ftInteger);
       CDS.FieldDefs.Add('Caption', ftString, 30);
       CDS.CreateDataSet;

     finally
       UpdateResultLabel(0);
     end;
    end;

    procedure TForm30.UpdateResultLabel(tc: Cardinal);
    begin
     lblResult.Caption := Format('RecordCount: %d; TotalTime: %d', [CDS.RecordCount, tc]);
    end;

    end.

  • Ega23 © (29.12.11 13:14) [9]
    1000 записей - мгновенно.
    10000 записей - 47 мс.
    100000 записей - почти 3 секунды (2891 мс).
    500000 записей - 82 секунды с волосьями.
    Миллион - таки да, надоело ждать.
    Но кому нахрен нужно полмиллиона записей????
  • Jeer © (29.12.11 19:53) [10]

    > Но кому нахрен нужно полмиллиона записей?


    Спасибо, что не затеял тест 1T записей in memory :)
  • Jeer © (29.12.11 19:55) [11]

    > просто наверное самое лучшее из таблиц в памяти


    Голословно/бездоказательно. "Ф топку" (С)
  • Alex_C (30.12.11 09:35) [12]

    > Голословно/бездоказательно.


    По скорости работы - VolgaTable самая быстрая из всех тестируемых мной таблиц в памяти. По всем показателям - сортировка, вставка. Какое еще доказательство нужно?


    > 1000 записей - мгновенно.
    > 10000 записей - 47 мс.
    > 100000 записей - почти 3 секунды (2891 мс).
    > 500000 записей - 82 секунды с волосьями.


    Про 100000 ничего не напутал?
    У меня так получилось:
    1000 - мгновенно.
    10000 - 141 мс.
    100000 - около 13 сек (ну уж никак не 3 сек!!!)
  • Ega23 © (30.12.11 09:49) [13]

    > По скорости работы - VolgaTable самая быстрая из всех тестируемых
    > мной таблиц в памяти. По всем показателям - сортировка,
    > вставка. Какое еще доказательство нужно?


    TSI5TokenDictionary гораздо быстрее. 1.2 миллиона записей грузятся ~ за секунду, поиск - мгновенный. И чо?

    Ещё раз: если ты сможешь внятно объяснить, нахрена тебе 100.000 записей в памяти, то можно попытаться найти решение проблемы. Если это тупая блажь, то и разговаривать не о чем.


    > Про 100000 ничего не напутал?

    Ничего.
  • sniknik © (30.12.11 11:19) [14]
    > По всем показателям - сортировка, вставка. Какое еще доказательство нужно?
    "сортировка" с созданием локального индекса сравнивается с сортировкой по указателям? ламер. какое еще доказательство нужно?
  • Jeer © (30.12.11 12:03) [15]

    > Про 100000 ничего не напутал?
    > У меня так получилось:
    > 1000 - мгновенно.
    > 10000 - 141 мс.
    > 100000 - около 13 сек (ну уж никак не 3 сек!!!)


    Возможно разные машины.
    Мне тоже приходилось заниматься использование таблиц в памяти для достаточно больших объемов.
    Сравнивал разные типы и подходы, создав тестовое приложение.

    Запустил тот тест и вот, что получил сейчас:
    *.FieldDefs.Add(F1, ftInteger, 0, False);
    *.FieldDefs.Add(F2, ftString, 64, False);
    Без каких-либо индексов, сортировок и ПК

    DBISAM
    10k - 0.95 s
    30k - 6.9 s
    50k - 18.3 s
    100k - 73 s

    FLAT
    10k - 0.13 s
    30k - 1.0 s
    50k - 2.7 s
    100k -10.5 s

    CDS
    10k - 0.28 s
    30k - 2.1 s
    50k - 4.7 s
    100k - 21 s

    Понятно, что от тачки зависит еще.
  • Alex_C (30.12.11 14:45) [16]

    > ламер.


    Ругаться не надо. Особенно в перед НГ! :) Девушки любить не будут! :)


    > нахрена тебе 100.000 записей в памяти


    У радиолюбителей есть разные дипломы. У любителей УКВ - есть диплом - сколько "квадратов" сработанно. Весь мир поделен на 32 тыс. больших квадратов от AA00 до RR99. При выболе диплома названия этих квадратов генерятся в цикле.
  • Jeer © (30.12.11 15:06) [17]

    > У радиолюбителей есть разные дипломы.


    У программистов - тоже.
    Скорее всего Вы что-то не так делаете. Архитектурно  - не так.
  • Jeer © (31.12.11 17:43) [18]

    > Весь мир поделен на 32 тыс. больших квадратов от AA00 до
    > RR99. При выболе диплома названия этих квадратов генерятся
    > в цикле.


    Смысла загонять все это в память не видно.
    Если стоит задача учета "посещенных" квадратов, достаточно один раз сгенерить таблицу всех 32 тыщ. квадратов в базе и проверять/проставлять признак "наличие".
  • Alex_C (01.01.12 23:03) [19]

    > Если стоит задача учета "посещенных" квадратов, достаточно
    > один раз сгенерить таблицу всех 32 тыщ. квадратов в базе
    > и проверять/проставлять признак "наличие".


    Вот теперь самое интересное:
    давно хотел спросить - как более правильно - 1 раз сгенерить, и потом уже использовать готовую таблицу (так конечно быстрее, но и объем справочной таблицы увеличиться), или генерить? Ранее генерил, т.к. у многих были еще очень маленькие флешки (а моя программа должна с флешки работать). Сейчас уже флешку менее 2 гиг не найти. Правильно я так понимаю сгенерить и сохранять все в справочной БД (да, забыл сказать - таких сгенеренных таблиц у меня несколько - но вот эта с квадратами - самая большая).
 
Конференция "Базы" » ClientDataSet as memtable - тормозит при добавлении записей [D7]
Есть новые Нет новых   [134431   +11][b:0][p:0.002]