Я конечно же имел в виду массив строк(длинных).zub писал(а):строки какраз SetLength`ом не инятятся, в там только в конце 0 пишется, в середине мусор будет.
О производительности динамических массивов...
Модератор: Модераторы
Кстати да ! Указанная в начале размерность массива давно уже не мешает выходить за ее рамки.zub писал(а):>>Классические массивы могут динамически менять размер?
а че нет? выделяешь память, копируешь старое, и не инитишь новое. какраз ка ты хочешь
( Кстати интересно почему? Раньше вроде нужно было специальный ключ ставить ({$R-} кажется ) )
Зы
Начал постепенно править старые скрины в темах . (Косяк не мой, а якобы "крик души хостеров" но мне всеравно стыдно...)
( Такое впечатление что это "заранее спланированная засада" сайт был в зоне .info и какое он отношение к печально известным событиям имеет совершенно непонятно... возможно что это вообще взлом совершенно ЧУЖОГО сервера . ) )
Последний раз редактировалось Alex2013 08.09.2022 09:06:51, всего редактировалось 1 раз.
>>Кстати да !
нет. так делать не надо. перевыделяешь память под массив
нет. так делать не надо. перевыделяешь память под массив
Кстати, если какие-то фичи стандартного динамического массива кажутся избыточными, теперь можно же замутить свой собственный вариант.
Я себе давно сделал велосипед (не через managed record или что iskander подразумевает, а через ручную работу с RTTI и заголовком массива), который как раз в порядке багофичи не зануляет элементы (если они неуправляемые). Но мне это нужно было не потому, что я очень страдал от лишних занулений, а потому, что я очень страдал без универсальной поддержки capacity, и, в меньшей степени, потому, что вместо Push(x) предпочитаю Grow^ := x, особенно если хочется создать объект сразу на месте:
Преимущество этого варианта перед чем-нибудь вроде TFPGList в том, что для 20 массивов разных типов создаются 20 компактных записей RTTI, с которыми работают одни и те же функции (я не только и не столько про свои, сколько про встроенные fpc_dynarray_setlength и т. д.), а дженерик 20 раз продублирует весь свой код.
Код: Выделить всё
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.зачем проверять если из определения и для них не надо...iskander писал(а): попробуйте проверить это предположение для строк, например.
Pchar - нулевой маркер часть самой строки.
Для всех остальных длина строки явно указывается в начале строки и все что лишнее отбрасывается при приведении типа...
Так что вообще нигде не нужно заполнение нулевыми битами...
Перешла икота на Федота.
При чем здесь PChar и нулевой маркер, речь же шла про динамические массивы, верно?
Вот вам пример для массива строк:
При чем здесь 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.
- Alexander
- энтузиаст
- Сообщения: 865
- Зарегистрирован: 18.12.2005 18:10:00
- Откуда: оттуда
- Контактная информация:
Работает. И именно быстрее. Только на что бы заменить 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
На PByte? И ещё P^ заменить на PТолько на что бы заменить PByteArray для снятия ограничение размера в type TByteArray = array [0..32767] of Byte; и warning при компиляции со значением больше 32767 ?
Заменил во втором бенче встроенный динамический массив на вот эту самоделку и получил:
Код: Выделить всё
9079
12742320
19900
9079
12742320
19900
>>на вот эту самоделку и получил
там в основе классический массив
там в основе классический массив
zub, можешь развить мысль?zub писал(а):там в основе классический массив
>>Заменил во втором бенче встроенный динамический массив на вот эту самоделку и получил:
а в этой самоделке в основе не динамический массив, а классический. выходит динамический массив вышел из теста
а в этой самоделке в основе не динамический массив, а классический. выходит динамический массив вышел из теста
Да нет там никакого классического массива, это имитация динамического массива с GetMem/FreeMem под капотом.
