О производительности динамических массивов...

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Re: О производительности динамических массивов...

Сообщение iskander » 07.09.2022 17:40:53

zub писал(а):строки какраз SetLength`ом не инятятся, в там только в конце 0 пишется, в середине мусор будет.

Я конечно же имел в виду массив строк(длинных).
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: О производительности динамических массивов...

Сообщение Alex2013 » 07.09.2022 17:50:27

zub писал(а):>>Классические массивы могут динамически менять размер?
а че нет? выделяешь память, копируешь старое, и не инитишь новое. какраз ка ты хочешь


Кстати да ! Указанная в начале размерность массива давно уже не мешает выходить за ее рамки.
( Кстати интересно почему? Раньше вроде нужно было специальный ключ ставить ({$R-} кажется ) )
Зы
Начал постепенно править старые скрины в темах . (Косяк не мой, а якобы "крик души хостеров" но мне всеравно стыдно...)
( Такое впечатление что это "заранее спланированная засада" сайт был в зоне .info и какое он отношение к печально известным событиям имеет совершенно непонятно... возможно что это вообще взлом совершенно ЧУЖОГО сервера . ) )
Последний раз редактировалось Alex2013 08.09.2022 10:06:51, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: О производительности динамических массивов...

Сообщение zub » 07.09.2022 19:27:27

>>Кстати да !
нет. так делать не надо. перевыделяешь память под массив
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: О производительности динамических массивов...

Сообщение iskander » 07.09.2022 20:49:26

Кстати, если какие-то фичи стандартного динамического массива кажутся избыточными, теперь можно же замутить свой собственный вариант.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: О производительности динамических массивов...

Сообщение runewalsh » 08.09.2022 04:13:29

Я себе давно сделал велосипед (не через managed record или что iskander подразумевает, а через ручную работу с RTTI и заголовком массива), который как раз в порядке багофичи не зануляет элементы (если они неуправляемые). Но мне это нужно было не потому, что я очень страдал от лишних занулений, а потому, что я очень страдал без универсальной поддержки capacity, и, в меньшей степени, потому, что вместо Push(x) предпочитаю Grow^ := x, особенно если хочется создать объект сразу на месте:

Код: Выделить всё
type
   Ary = type pointer; // Тип, к которому можно кастовать динамические массивы.

   AryHelper = type helper for Ary // Методы для работы с ними.
      ...
      function Grow(typeInfo: pointer; var n: SizeUint): pointer;
   end;

   SomeType = record
      ...
      procedure Setup(...);
   end;

var
   a: array of SomeType;
   na: SizeUint; // логическое количество элементов 'a'

begin
   na := 0;
   SomeType(Ary(a).Grow(TypeInfo(a), na)^).Setup(...);
   // Теперь na = 1, а length(a) — аналог capacity у TList и может быть больше.
end.

Преимущество этого варианта перед чем-нибудь вроде TFPGList в том, что для 20 массивов разных типов создаются 20 компактных записей RTTI, с которыми работают одни и те же функции (я не только и не столько про свои, сколько про встроенные fpc_dynarray_setlength и т. д.), а дженерик 20 раз продублирует весь свой код.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: О производительности динамических массивов...

Сообщение beria » 08.09.2022 13:09:16

iskander писал(а): попробуйте проверить это предположение для строк, например.

зачем проверять если из определения и для них не надо...
Pchar - нулевой маркер часть самой строки.
Для всех остальных длина строки явно указывается в начале строки и все что лишнее отбрасывается при приведении типа...
Так что вообще нигде не нужно заполнение нулевыми битами...
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

Re: О производительности динамических массивов...

Сообщение iskander » 08.09.2022 15:58:47

Перешла икота на Федота.
При чем здесь PChar и нулевой маркер, речь же шла про динамические массивы, верно?
Вот вам пример для массива строк:
Код: Выделить всё
program test;

{$mode objfpc}{$h+}

uses
  SysUtils;

procedure StrArrayTest;
var
  StrArray: PString = nil;
  I: Integer;
const
  Len = 100;
begin
  GetMem(StrArray, Len * SizeOf(string));
  try
    FillChar(StrArray^, Len * SizeOf(string), 42); //замусорим выделенную память
    Initialize(StrArray^, Len); //если закомментировать Initialize(), оно брякнется
    for I := 0 to Len - 1 do
      StrArray[I] := I.ToString;
    WriteLn(StrArray[Len - 1]);
    Finalize(StrArray^, Len);   //если закомментировать Finalize(), 100 строк утекут
  finally
    FreeMem(StrArray);
  end;
end;

begin
  StrArrayTest;
  ReadLn;
end.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: О производительности динамических массивов...

Сообщение Alexander » 12.09.2022 09:52:50

Работает. И именно быстрее. Только на что бы заменить PByteArray для снятия ограничение размера в type TByteArray = array [0..32767] of Byte; и warning при компиляции со значением больше 32767 ?

Код: Выделить всё
program project1;

{$mode objfpc}{$H+}

uses
{$IFDEF UNIX}
  cthreads,
     {$ENDIF}
  Classes,
  SysUtils { you can add units after this };

  var
  Ar: array of byte;
  P:  PByteArray;
  i,t : longint;
begin
  t := GetTickCount64;
  for i := 0 to 100000 do
  begin
    SetLength(Ar, 1000000);
    Ar[100] := 100;
    SetLength(Ar, 500);
    if Ar[100] <> 100 then writeln('error:SetLength');
    Ar[9] := 9;
    SetLength(Ar, 0);
  end;
  writeln(GetTickCount64 - t);
  t := GetTickCount64;
  for i := 0 to 100000 do
  begin
    GetMem(P, 1000000);
    (P^)[100000] := 100;
    ReallocMem(P, 500);
   if (P^)[100000] <> 100 then writeln('error:ReallocMem');
    (P^)[9] := 9;
    FreeMem(P);
  end;
  writeln(GetTickCount64 - t);
  readln;
end.


Код: Выделить всё
first@my:~/mysoft/testdynarr$ fpc t2.pas
Free Pascal Compiler version 3.2.2 [2021/05/16] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling t2.pas
t2.pas(32,10) Warning: range check error while evaluating constants (100000 must be between 0 and 32767)
t2.pas(34,12) Warning: range check error while evaluating constants (100000 must be between 0 and 32767)
Linking t2
39 lines compiled, 0.4 sec
2 warning(s) issued

first@my:~/mysoft/testdynarr$ ./t2
13923
12
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 690
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Re: О производительности динамических массивов...

Сообщение Дож » 12.09.2022 10:14:29

Только на что бы заменить PByteArray для снятия ограничение размера в type TByteArray = array [0..32767] of Byte; и warning при компиляции со значением больше 32767 ?

На PByte? И ещё P^ заменить на P
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: О производительности динамических массивов...

Сообщение Alexander » 12.09.2022 12:17:02

Спасибо !
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 690
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Re: О производительности динамических массивов...

Сообщение iskander » 26.09.2022 17:12:53

Заменил во втором бенче встроенный динамический массив на вот эту самоделку и получил:
Код: Выделить всё
9079
12742320
19900

9079
12742320
19900
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: О производительности динамических массивов...

Сообщение zub » 26.09.2022 18:00:36

>>на вот эту самоделку и получил
там в основе классический массив
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: О производительности динамических массивов...

Сообщение iskander » 26.09.2022 18:03:36

zub писал(а):там в основе классический массив

zub, можешь развить мысль?
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: О производительности динамических массивов...

Сообщение zub » 26.09.2022 18:10:07

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

Re: О производительности динамических массивов...

Сообщение iskander » 26.09.2022 18:33:23

Да нет там никакого классического массива, это имитация динамического массива с GetMem/FreeMem под капотом.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Пред.След.

Вернуться в Free Pascal Compiler

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

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

Рейтинг@Mail.ru