ООП: доступ к методу класса из-вне

Вопросы программирования и использования среды Lazarus.

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

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 28.05.2016 02:26:18

Не впевен - потому что слишком большая (3 раза) разница в потреблении памяти.

Добавляйте аналог
Код: Выделить всё
setlength(arr1,TEST_CNT*4);

в вариант fpc-stl и всё станет также и скорость и память.

Добавлено спустя 12 минут 20 секунд:
Ваш "нечесный вариант"
zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-dynarr

real 0m0.168s
user 0m0.160s
sys 0m0.004s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-stl

real 0m0.191s
user 0m0.160s
sys 0m0.012s

Делаем всё по справедливости добавляя arr1.Reserve(Test_cnt*4)
zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-stl

real 0m0.168s
user 0m0.156s
sys 0m0.012s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-dynarr

real 0m0.179s
user 0m0.172s
sys 0m0.004s


Добавлено спустя 2 минуты 11 секунд:
>>В реальных задачах заказывают место не поэлементно, а порциями с запасом - тем более что по потреблению памяти этот вариант экономнее, чем прочие, в 3..5 раз
Естественно, тут вы точно сказали сколько элементов понадобится, остальные были вынуждены догадываться))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение debi12345 » 28.05.2016 02:59:51

Добавил команду Rеserve - уже лучше - проигрыш динэррэю только 10..15% (на i5-4570).
А вот прожорливость (это еще мягко сказано - 3 раза!) памяти у STL-варианта - это ооочень нехорошо, придется иметь ввиду. Но SDL-вариант жрет еще в 2 раза больше памяти чем STL. Так что STL-реализация выглядит неплохой "золотой серединой" :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 28.05.2016 03:37:03

Глянул сам тест... ну ведь они совершенно разные. Я сначала за выделения памяти зацепился, но остальное тоже нужно править. кароче вот вариант стл идентичный динmассиву. расход памяти замерте.
Код: Выделить всё
program test_stl;
{$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=specialize TVector<anydatarecty>;


procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
var
   adata:anydatarecty;
begin
  adata.data_type:= atype;
  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;
i: integer;

begin
  arr1:=anydatarecarty.Create;
  arr1.Reserve(TEST_CNT*4);
  for i:= 0 to TEST_CNT-1 do begin
    arr1.Mutable[i]^.ival:= i;
   arr1.Mutable[i + TEST_CNT]^.rval:= double(i+1);
    arr1.Mutable[i + TEST_CNT*2]^.tval:= pchar(inttostr(i) + ' as text');
//    chmo1.int_val:= i;
//    chmo1.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
   arr1.Mutable[i + TEST_CNT*3]^.chmoval.int_val:= i;
    arr1.Mutable[i + TEST_CNT*3]^.chmoval.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
  end;
  for i:= 0 to TEST_CNT-1 do begin
  arr1.Mutable[i]^.ival:= arr1[i].ival +1;
  end;
  arr1.Destroy;

end.   

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-stl

real 0m0.101s
user 0m0.100s
sys 0m0.000s
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение debi12345 » 28.05.2016 04:04:44

расход памяти замерте.

Тайминги и память - 1:1-клон dynarray-варианта.

Добавлено спустя 11 часов 44 минуты 37 секунд:
Видимо компилятор применяет к STl несколько шаблонов в зависимости от используемого функционала - если запрашиваются индексные методы,то используется быстрая DynArray-реализация, а если запрашиваются динамические манипуляции о списками, то используется медленная и жадная до памяти DynList-реализация.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 11.08.2016 02:35:33

debi12345
В fpc появился еще один контейнер - делфисовместимый модуль generics.collections
Взял исходный вариант test_stl с начальным размером массива=1 и множественным перевыделением массива при его заполнении
предидущие тесты приводил с линя х64, сейчас сравниваю на той же машине но в семерке, fpc 32разрядный, delphi xe хз какой разрядности
Код: Выделить всё
program test_rtl;
{$mode delphi}{$h+}

uses
  sysutils,strings,generics.collections;

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=TList<anydatarecty>;

procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
var
   adata:anydatarecty;
begin
  adata.data_type:= atype;
  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.add(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:= (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.count-1 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);
        StrDispose(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, '}');
        StrDispose(arr1[i].chmoval.str_val);
      end;
    end;
  end;
  arr1.Destroy;
end.       

Код: Выделить всё
program test_rtl_delphi;
{$h+}

uses
  sysutils,generics.collections;

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=TList<anydatarecty>;

procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
var
   adata:anydatarecty;
begin
  adata.data_type:= atype;
  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.add(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:= (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.count-1 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);
        StrDispose(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, '}');
        StrDispose(arr1[i].chmoval.str_val);
      end;
    end;
  end;
  arr1.Destroy;
end.   

Код: Выделить всё
program test_stl;
{$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=specialize TVector<anydatarecty>;


procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
var
   adata:anydatarecty;
begin
  adata.data_type:= atype;
  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-1 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);
        StrDispose(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, '}');
        StrDispose(arr1[i].chmoval.str_val);
      end;
    end;
  end;
  arr1.Destroy;
end.   


Z:\hdd\src\my\algotests\algo_test>TimeMem-1.0.exe test-stl.exe
Exit code : 0
Elapsed time : 0.16
Kernel time : 0.02 (9.9%)
User time : 0.12 (79.0%)
page fault # : 17765
Working set : 47500 KB
Paged pool : 84 KB
Non-paged pool : 6 KB
Page file size : 55060 KB

Z:\hdd\src\my\algotests\algo_test>TimeMem-1.0.exe test-rtl-delphi.exe
Exit code : 0
Elapsed time : 0.14
Kernel time : 0.03 (23.1%)
User time : 0.09 (69.3%)
page fault # : 18030
Working set : 52360 KB
Paged pool : 81 KB
Non-paged pool : 8 KB
Page file size : 51556 KB

Z:\hdd\src\my\algotests\algo_test>TimeMem-1.0.exe test-rtl.exe
Exit code : 0
Elapsed time : 0.17
Kernel time : 0.00 (0.0%)
User time : 0.16 (94.5%)
page fault # : 18374
Working set : 39572 KB
Paged pool : 84 KB
Non-paged pool : 6 KB
Page file size : 41648 KB

Оптимизации не включал, trunk fpc против delphi xe
((
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение Aleh » 17.08.2016 15:44:29

Практическое применение вопроса:(используется AnchorDocking, какие формы нужны - на старте программе не известно)
меня правда интересуют в первую очередь данные, хотя бы стандартных классов, особенно TForm.

Есть функция
RegisterFormFrame(Form1: TTForm; aName:string; Multi:boolean; Admin:boolean):integer;
где TTForm = class of TForm;

пример использования
initialization
RegisterFormFrame(TfmUserEtaps, 'Доступные этапы', false, false);
end.

По сути-это сборщик всех форм в программе для их централизованного использования. Единственное, что я могу получить из описания класса
s:=Form1.ClassName; Delete(s, 1, 1); - имя будущего экземпляра класса. :cry: :cry: :cry: :cry: :cry: :cry: Аминь.
TfmUserEtaps - Т = fmUserEtaps, и только потому, что я использую "стандартное" соглашение о названиях.
а мог обратится к Form1.Caption - не надо было передавать aName:string в RegisterFormFrame, мог посмотреть наличие fmUserEtaps.FormShow - знал бы, что форма использует подключение к главной базе данных и т.п. В простой форме, кроме "великого Tag", найдётся с десяток свойств, которые можно использовать по своему усмотрению.

На текущий момент он добавляет в меню "окна" пункт 'Доступные этапы' а в создаваемый MenuItem.Hint имя fmUserEtaps, что бы стало возможным вызвать любую форму строчкой
if sender is TMenuItem then
DockMaster.ShowControl((sender as TMenuItem).Hint, true);
и ГЛАВНОЕ - обеспечить нормальную работу DockMaster при загрузке любой компоновки (DockMaster.LoadLayoutFromConfig(XMLConfig,true))

если попытаться создать экземпляры классов - программа грузится мин15 (32 бинная вылетает на 11мин -мало памяти)
полдня пытался найти способ получения свойств - бросил из-за отсутствия хоть малюсенького результата.
Aleh
новенький
 
Сообщения: 53
Зарегистрирован: 08.08.2016 12:27:45

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 17.08.2016 17:42:42

От передачи имени никуда не денешся. Имя класса формы и имя формы - разные вещи.

Код: Выделить всё
DockMaster.ShowControl((sender as TMenuItem).Hint, true);

Хинт это хинт, хранить в нем чтото другое - некрасиво))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение Aleh » 17.08.2016 18:21:42

zub писал(а):От передачи имени никуда не денешся. Имя класса формы и имя формы - разные вещи.

... но конструктор класса формы "знает" имя формы, Caption, таг, хинт и всё остальное. Вот в чем фокус. Как бы его расспросить? Тогда и имя передавать не нужно было.
Aleh
новенький
 
Сообщения: 53
Зарегистрирован: 08.08.2016 12:27:45

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 17.08.2016 18:45:09

Конструктор ничего не знает. знает
Код: Выделить всё
Application.CreateForm(InstanceClass: TComponentClass; out Reference);

и знает это из соответствующего lfm в ресурсах файла.
ИМХО правильно передавать не только имя но и процедуру(функцию, метод...) создающую форму, это будет гораздо универсальней чем просто "унивесальный" вызов конструктора
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение Лекс Айрин » 17.08.2016 18:51:13

А разве это не доступно через интерфейсы?
Код: Выделить всё
property Name: TComponentName read FName write SetName stored False;
property Tag: PtrInt read FTag write FTag default 0;
property Caption stored IsForm;
property Hint: TTranslateString read FHint write SetHint stored IsHintStored;

Пусть и не все определено в самой форме (клвссе TForm), но оно там все есть и легко доступно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: ООП: доступ к методу класса из-вне

Сообщение Aleh » 18.08.2016 12:19:28

zub писал(а):и знает это из соответствующего lfm в ресурсах файла.

Вот спасибо! А я про их совсем забыл. Попробовал-работает в принципе, понадобится для дела - допилю.
здесь viewtopic.php?f=5&t=3285&p=22448 нюансики обсуждаются.
А Application.CreateForm тоже ничего не знает, в итоге вызывает по сути конструктор TObject.

Лекс Айрин писал(а):А разве это не доступно через интерфейсы?

А вот с интерфейсами никогда не работал, может примерчик или ссылку...
Aleh
новенький
 
Сообщения: 53
Зарегистрирован: 08.08.2016 12:27:45

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 18.08.2016 13:30:17

Лекс Айрин
Ты про что то не про то))

Aleh
Незачто. Не надо это использовать.
RegisterFormЧтотоТам(ЧтоТоДляСозданияФормы,ЧтоТоДляИдентификацииФормы); - Вполне общепринятый подход. Зачем подвязывать его на голое форпмошлепство?

>>А Application.CreateForm тоже ничего не знает, в итоге вызывает по сути конструктор TObject.
Понятно что вызывается конструктор, но десериализацией формы из ресурсов конструктор не занимается - он создаст всё с значениями по умолчанию.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение Лекс Айрин » 18.08.2016 13:46:26

Aleh
Да ладно... все, ну может кроме некоторых консольщиков, работали. Взять тот же Caption (определение чуть выше).. если не знать, что это интерфейс, то ничем, с точки зрения программиста, не отличишь от обычной строковой переменной.

Код: Выделить всё
MyFile := ParamStr(1);
      FMain.Caption := MyFile  + '             LexEditor';




справка, к сожалению, дельфовская, но подходит http://pascal-study.blogspot.ru/2012/05 ... .html#more

zub возможно. Но согласно ООП property это интерфейс. И, возможно, я не учитываю на каком этапе хотят поменять значения.

Добавлено спустя 2 минуты 31 секунду:
zub писал(а):он создаст всё с значениями по умолчанию.


Интересно, откуда они берутся?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 18.08.2016 14:14:11

>>Интересно, откуда они берутся?
Чудес не бывает, бывает "магия" компилятора и присвоение значений напрямую в конструкторе

Добавлено спустя 3 минуты 10 секунд:
...кроме некоторых консольщиков... ...что это интерфейс... ...от обычной строковой переменной...

моя твоя непонимай. ты про проперти чтоли? они не про это))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение Лекс Айрин » 18.08.2016 20:20:38

zub, так и они про проперти речь завели... по крайней мере...
Aleh писал(а):... но конструктор класса формы "знает" имя формы, Caption, таг, хинт и всё остальное. Вот в чем фокус. Как бы его расспросить?


речь явно про них.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Пред.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru