Динамический массив любого типа

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Динамический массив любого типа

Сообщение debi12345 » 21.07.2013 20:58:06

вот и получается - сколькото довыделений и сколькото полноценных выделений с перемещением

А как насчет StrNew(Pchar) vs AnsiString(refcounting) ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Динамический массив любого типа

Сообщение Mirage » 21.07.2013 23:09:49

По поводу исходной проблемы:
Есть класс-враппер для динамического массива любого типа.
http://blog.synopse.info/post/2011/03/1 ... -fast-RTTI
Умеет в том числе и размер менять.
Можно посмотреть как там реализована setCapacity().
А можно и использовать готовое, чем черт не шутит.

Вообще надо уже как-то прекращать этот велосипедный беспредел. Например, создать что-то вроде apache foundation. Еще необходим стандарт на подтягивание зависимостей.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Динамический массив любого типа

Сообщение zub » 22.07.2013 02:30:45

debi12345
>>А как насчет StrNew(Pchar) vs AnsiString(refcounting)?
много в вашем массиве будет одинаковых строк? Думаю их вообще небудет - если откуданибудь извне прочитать 300К одинаковых строк - они всеравно будут "разными" а не одной строкой с refcount=300К. в данной примере разницы ИМХО вообще не будет - стринги всеравно создаются из пчаров копированием, а потом уничтожается

Добавлено спустя 1 минуту 21 секунду:
Mirage
>>Вообще надо уже как-то прекращать этот велосипедный беспредел.
fpc-stl чем не велокиллер? тем что на генериках?
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Динамический массив любого типа

Сообщение debi12345 » 22.07.2013 08:09:26

fpc-stl чем не велокиллер?

А на нем можно сделать данную задачу ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Динамический массив любого типа

Сообщение Mirage » 22.07.2013 12:50:09

zub писал(а):fpc-stl чем не велокиллер? тем что на генериках?

Совместим с Delphi?
Я, например, о нем первый раз слышу, да и подозреваю он только о контейнерах.
С трудом нагуглил что-то об этой либе - ПДФку.
Сразу:
TSet is an ordered container of unique elements
THashSet is an unordered container of unique elements
Т.е. просто TSet у них это то, что должно называться TTreeSet.
Короче, именование неконсистентно.
Кстати, библиотек с контейнерами полно на любой вкус. Стандарта нет. Т.е. той, которую будут использовать с наибольшей вероятностью. Мне, например непонятно, зачем использовать fpc-stl.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Динамический массив любого типа

Сообщение zub » 22.07.2013 21:28:31

debi12345
>>на нем можно сделать данную задачу ?
а почему нет, это просто обертка над динмассивом с допфичами

Mirage
С делфи не совместим.
Использовать пакет идущий в составе fpc думаю надежней чем чтото сторонее
>>Короче, именование неконсистентно.
хз, незнаком с такими тонкостями
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Динамический массив любого типа

Сообщение debi12345 » 22.07.2013 23:04:20

это просто обертка над динмассивом с допфичами

Но элементы-тов нашей задаче разнородые - то есть опять придется использовать TObject как элемент массива - то есть темплэйтовость (настройка на тип) аннулируется. В чем тогда преимущево над Вашим вариантом "1" ? Позволит обойтись без SetLength ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Динамический массив любого типа

Сообщение zub » 22.07.2013 23:38:44

>>Но элементы-тов нашей задаче разнородые
в смысле разнородные - однородные - с одинаковым sizeof и индексным доступом.

zamtmn@zamtmn-desktop:/mnt/wind/array$ time ./v4
Heap dump by heaptrc unit
1800025 memory blocks allocated : 124043278/129349960
1800025 memory blocks freed : 124043278/129349960
0 unfreed memory blocks : 0
True heap size : 57376768
True free heap : 57376768

real 0m1.256s
user 0m1.224s
sys 0m0.028s

zamtmn@zamtmn-desktop:/mnt/wind/array$ time ./v4

real 0m0.235s
user 0m0.208s
sys 0m0.024s

вариант с fpc-stl скоростью не блестанул, причем что добавлять элементы по одному, что выделить под них память сразу - отличается несильно. первый запуск был с -gh, второй соответственно без него
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Динамический массив любого типа

Сообщение Mirage » 23.07.2013 02:05:31

Т.е. оно еще и тормоз? Куда уж тут до велокиллера...
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Динамический массив любого типа

Сообщение debi12345 » 23.07.2013 02:15:59

Тоже довольно быстрый код - на базе DCALC (юниты приатачены) :
Код: Выделить всё
program test;

{$mode objfpc}{$h+}

uses
  decal          in 'decal\decal.pas',
  mwfixedrecsort in 'decal\mwfixedrecsort.pas',
  sysutils,
  classes
;
const
  TEST_CNT = 300000;

type

  chmoclass = class
   public
    int_val: integer;
    str_val: widestring;
    constructor create(const aint: integer; const astr: widestring);
  end;

  constructor chmoclass.create(const aint: integer; const astr: widestring);
  begin
    int_val:= aint;
    str_val:= astr;
  end;

  procedure PrintData(ptr: pointer; const obj: dobject);
  begin
  case obj.vtype of
    vtInteger:   
      writeln('atomic int = ',asInteger(obj));
    vtString,vtWidestring:
      writeln('atomic widestring = ',asWideString(obj));
    vtExtended:
      writeln('atomic real = ',asEXtended(obj));
    vtObject: begin
      with chmoclass(asClass(obj)) do begin
        writeln('chmo data = {',int_val,',',str_val,'}');
        free;
      end;
    end;
  end;
  end;

var
  lst1: dlist;
  i: integer;

begin

  lst1:= dlist.create;
  for i:= 0 to TEST_CNT do begin
    lst1.add([i]);
    lst1.add([extended(i)]);
    lst1.add([widestring(inttostr(i) + ' as text')]);
    lst1.add([chmoclass.create(i,inttostr(i) +' as text in CHMOREC')]);
  end;

  foreach(lst1,MakeApply({$ifdef fpc}@{$endif}PrintData));
  lst1.free;

end.


Особенности:
1) использует связанный список вместо массива - это позволяет отказаться от SETLENGTH
2) можно работать с родными рефкаунтед-строками вместа ненативного динпамятного PCHAR
Конструктор класса (реально без указания предка = TOBJECT ) в принципе можно вынести в INLINE.

Напишите сколько у Вас получается.
Вложения
decal.rar
(50.67 КБ) Скачиваний: 436
Последний раз редактировалось debi12345 23.07.2013 02:32:26, всего редактировалось 1 раз.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Динамический массив любого типа

Сообщение zub » 23.07.2013 02:30:44

вариант с decal`ом. вывод массива закоментирован
zamtmn@zamtmn-desktop:/mnt/wind/array/v5$ time ./v5

real 0m0.360s
user 0m0.316s
sys 0m0.040s


>>Т.е. оно еще и тормоз? Куда уж тут до велокиллера...
не тормоз. выше я озвучил результаты для вариантов без setlength - массив был выделен за 1 раз. а в тесте с фпцстлным tvector идет добавление в массив по одному элементу
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Динамический массив любого типа

Сообщение debi12345 » 23.07.2013 02:38:26

На моей машине в 3 раза обгоняет мой (1-й) вариант - котрый с поэлементным SETLEGHTH. Резервирование памяти с запасом для более редкой реаллокации в случае списка не нужно в принципе.
Можно потестирвать и другие типы STL - и DCALC-контейнеров :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Динамический массив любого типа

Сообщение zub » 23.07.2013 02:52:16

Ваш эталонный вариант с вариантным рекордом и поэлементным добавлением у меня выдал
zamtmn@zamtmn-desktop:/mnt/wind/array$ time ./v0

real 0m1.485s
user 0m0.776s
sys 0m0.704s
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Динамический массив любого типа

Сообщение debi12345 » 23.07.2013 11:37:55

Еще раз протестировал варианты с поэлементным (как это будет в реальной жизни) перераспределением :

1) копирование в VARIANT - не дождался завершения (!)
2) UNION-based : 4 сек
3) TOBJECT-based, минимальный размер элементов : 2 сек
4) TOBJECT-based, размер элементов с запасом: 5 сек
5) DCALC.DLIST : 1.5 сек
6) DCALC.DARRAY : 2 сек

Хм.. Пока что склоняюсь к вариантам на DCALC, плюс в них можно работать со строками, а не указателями на строки.
У Вас есть полный код примера на FPC-STL (2.6.2) ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Динамический массив любого типа

Сообщение zub » 23.07.2013 11:49:18

>>У Вас есть полный код примера на FPC-STL (2.6.2) ?
Код: Выделить всё
program v4;
{$mode objfpc}{$h+}

uses
  sysutils,strings,gvector;

const
  TEST_CNT = 300000;

type

  chmorec = packed record
    int_val: integer;
    str_val: pchar;
  end;
  pchmorec = ^chmorec;

  ANYTYPE = (INT_T,TEXT_T,REAL_T,CHMO_T);

  anydatarecty = packed record
    case data_type:ANYTYPE of
      INT_T:  (ival: integer);
      TEXT_T: (tval: pchar);
      REAL_T: (rval: double);
      CHMO_T: (chmoval: chmorec);
  end;
  //anydatarecarty = array of anydatarecty;
  anydatarecarty=specialize TVector<anydatarecty>;


procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
var
   adata:anydatarecty;
begin
  //setlength(arr,length(arr)+1);
  adata.data_type:= atype;

//  case integer(atype) of
//    integer(INT_T): arr[high(arr)].ival:= integer(adataptr^);
//    integer(TEXT_T): arr[high(arr)].tval:= strnew(pchar(adataptr));
//    integer(REAL_T): arr[high(arr)].rval:= double(adataptr^);
//    integer(CHMO_T): begin
//      with arr[high(arr)].chmoval do begin
//        int_val:= (chmorec(adataptr^)).int_val;
//        str_val:= strnew((chmorec(adataptr^)).str_val);
//      end;
//    end;
//  end;


  case atype of
    INT_T: adata.ival:= integer(adataptr^);
    TEXT_T: adata.tval:= strnew(pchar(adataptr));
    REAL_T: adata.rval:= double(adataptr^);
    CHMO_T: begin
      with adata.chmoval do begin
        int_val:= (chmorec(adataptr^)).int_val;
        str_val:= strnew((chmorec(adataptr^)).str_val);
      end;
    end;
  end;
  arr.PushBack(adata);


end;


var
arr1: anydatarecarty;
i1: integer;
pch1: pchar;
r1: double;
chmo1: chmorec;
i: integer;

begin
  arr1:=anydatarecarty.Create;
  for i:= 0 to TEST_CNT do begin
    i1:= i;
    addelem(arr1,INT_T,@i1);

    r1:= double(i);
    addelem(arr1,REAL_T,@r1);

    pch1:= pchar(inttostr(i) + ' as text');
    addelem(arr1,TEXT_T,pch1);

    chmo1.int_val:= i;
    chmo1.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
    addelem(arr1,CHMO_T,@chmo1);
  end;


  for i:=arr1.Size downto 0 do begin
    case integer(arr1[i].data_type) of
//    integer(INT_T):  writeln('int val = ',  arr1[i].ival);
      integer(TEXT_T): begin
//        writeln('text val = ', arr1[i].tval);
        dispose(arr1[i].tval);
      end;
//      integer(REAL_T): writeln('real val = ', arr1[i].rval);
      integer(CHMO_T): begin
//        writeln('chmo rec = {', arr1[i].chmoval.int_val,',',arr1[i].chmoval.str_val, '}');
        dispose(arr1[i].chmoval.str_val);
      end;
    end;
  end;
  arr1.Destroy;

end.

В зависимости проекта подключить FCL
На 2.6.x скорее всего придется самостоятельно скомпилировать fpc-stl, когда я пробовал эти версии он не компилировался при установке
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17

Рейтинг@Mail.ru