powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Список классов vs списка записей - в чем преимущество?
25 сообщений из 63, страница 1 из 3
Список классов vs списка записей - в чем преимущество?
    #39762359
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наткнулся на один интересный коммент Peter Below'a - https://en.delphipraxis.net/topic/576-maintaining-for-loops/?tab=comments#comment-4225
Instead of
Код: pascal
1.
Projects: TArray<TProject>


use a list class:
Код: pascal
1.
2.
3.
4.
type
  TProjectList = class(TList<TProject>)
    
  end;  


Add public methods to the class that implement your current for loops. This way you have all this code centralized in one place, which should massively simplify the maintenance. And while you're at it: convert the record into a class. Lists of records are a bit inefficient since accessing the items in the list involves a lot of copying of data. You can then use a TObjectlist<TProject> as base class for your TProjectlist and let the list manage the memory of the TProject objects you add to it (OwnsObjects parameter for the list constructor set to true, which is the default).
Может кто "разжевать" выделенное жирным?
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762365
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYingМожет кто "разжевать" выделенное жирным?

TObject это указатель. record это POD тип.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762372
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing,

очередная агитация за конвертить записи в классы, хотя казалось что идиоты кончились уже
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762378
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan)очередная агитация за конвертить записи в классы, хотя казалось что идиоты кончились уже
Да вроде как неудобно называть человека из команды TeamB идиотом :)
Так стоит все же следовать его совету или нет?
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762379
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYingТак стоит все же следовать его совету или нет?

Стоит мозгом подумать об отличии array of record от array of TObject.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762386
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYingkealon(Ruslan)очередная агитация за конвертить записи в классы, хотя казалось что идиоты кончились уже
Да вроде как неудобно называть человека из команды TeamB идиотом :)
Так стоит все же следовать его совету или нет?не стоит
чудные люди, наплодят дырявых абстракций, а потом советы раздают как с этим жить
сделай простую обёртку с получением адреса и все проблемы с производительностью исчезнут
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762387
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
- Дверь? Котора дверь?
- Котора дверь! Вот эта.
- Эта? Прилагательна.
- Почему ж?
- Потому что она приложена к своему месту.

всё хорошо в меру и к месту.
но есть ещё и МОДНЫЕ веяния...
а Петя Бигелоу, тот ещё "евангелист".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762389
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYingТак стоит все же следовать его совету или нет?Зависит от... Часто стоит в том числе и из-за перформанса.
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762391
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)чудные люди, наплодят дырявых абстракций, а потом советы раздают как с этим жить
сделай простую обёртку с получением адреса и все проблемы с производительностью исчезнутНу конечно лучше плодить костыли
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762392
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing,

Всё верно он говорит.

1. Что ты там будешь делать с TArray не понятно и не наглядно.
2. У массива нет методов
3. В результате - ты ничего не выигрываешь, кроме выноса мозга.
4. TList/TObjectList/TDictionary/TObjectDictionary - стандартные классы для работы со списками. Причём не только для Delphi. Не делай своих велосипедов.
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762393
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
21.01.2019 14:42, white_nigger пишет:
> Ну конечно лучше плодить костыли

не костыли, а аддоны!


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762402
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerНу конечно лучше плодить костылизачем костыли,
обычный перевод STL, всё апробовано и работает
нормальные итераторы, нормальные контейнеры без заскоков и выделения памяти на каждый чих

куда деваться если стандартная либа вся в ляпах и недоделках
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762413
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)LiYingпропущено...

Да вроде как неудобно называть человека из команды TeamB идиотом :)
Так стоит все же следовать его совету или нет?не стоит
чудные люди, наплодят дырявых абстракций, а потом советы раздают как с этим жить
сделай простую обёртку с получением адреса и все проблемы с производительностью исчезнут Все тут прям замучены нарзаном вопросом о производительности.
А количество тактов процессора ты уже посчитал, которые выиграет TArray<> против TList<>?
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762429
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimonka,

к производительности взывают создатели сего творения, что вызвало у LiYing вполне здравый вопрос
я просто говорю, что не вижу никакого смысла спорить кто быстрее черепаха или улитка
кому надо делают нормальные либы и не парятся
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762543
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ради быстродействия в своем TArrayEx<T> = record даже SetLength захакал. :)


Типа так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure TArrayEx<T>.SetLengthFast(NewValue: integer);
const
  GrowLimit = 64;
begin
  if NewValue<=0 then begin
    FCapacity:=0;
    SetLength(Items,0);
  end else begin
    if (NewValue>FCapacity) or (NewValue shl 1<FCapacity) then begin
      FCapacity:=Min(NewValue shl 1,NewValue+GrowLimit);
      SetLength(Items,FCapacity);
      FArrayCount:=PNativeInt(NativeInt(@Items[0])-SizeOf(NativeInt));
    end;
    FArrayCount^:=NewValue;
  end;
end;
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762552
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

Теоретик... Блин.
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762556
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaА количество тактов процессора ты уже посчитал, которые выиграет TArray<> против TList<>?
Дело не [только] в тактах, а в многократном выделении/освобождении кучи мелких кусочков памяти вместо одного большого.
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762560
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing,

надо не разжовывать выделенное, а смотреть, что дальше написано -- это самое главное. Генерики наше всё. На порядок ускоряет разработку и снижают рутину. Долой бесконечную копипасту с самописными списками и рекордами. А уж про отладку -- так это манна небесная. Все на броневичок генериков!
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762568
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JaDi,

одно другому не мешает
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762569
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gatorkealon(Ruslan),

Теоретик... Блин.хотелось бы, но ещё и код выдавать нужно
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762593
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatРади быстродействия в своем TArrayEx<T> = record даже SetLength захакал. :)


Типа так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure TArrayEx<T>.SetLengthFast(NewValue: integer);
const
  GrowLimit = 64;
begin
  if NewValue<=0 then begin
    FCapacity:=0;
    SetLength(Items,0);
  end else begin
    if (NewValue>FCapacity) or (NewValue shl 1<FCapacity) then begin
      FCapacity:=Min(NewValue shl 1,NewValue+GrowLimit);
      SetLength(Items,FCapacity);
      FArrayCount:=PNativeInt(NativeInt(@Items[0])-SizeOf(NativeInt));
    end;
    FArrayCount^:=NewValue;
  end;
end;



Чистым бредом попахивает, ей богу!

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
type
  ArrayEx<T> = record
    v: array of T;
    CurrentLength: NativeUInt;
    function add(Value: T): NativeUInt;
  end;

function ArrayEx<T>.add(Value: T): NativeUInt;
const
  Plus = 16; // 32
var
  MaxLength: Integer;
begin
  MaxLength := Length(v);
  if CurrentLength >= MaxLength then
    SetLength(v, MaxLength + Plus);

  v[CurrentLength] := Value;
  inc(CurrentLength);
end;



Что может быть легче ??? Ну если это медленно, из за использования length то давайте развратимся

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
type
  PDynArrayRec = ^TDynArrayRec;

  TDynArrayRec = packed record
{$IFDEF CPU64BITS}
    _Padding: Integer; // Make 16 byte align for payload..
{$ENDIF}
    RefCnt: Integer;
    Length: NativeInt;
  end;

  ArrayEx<T> = record
    v: array of T;
    CurrentLength: NativeUInt;
    function add(Value: T): NativeUInt;
  end;

function ArrayEx<T>.add(Value: T): NativeUInt;
const
  Plus = 16; // 32
var
  MaxLength: Integer;
begin
  if PDynArrayRec(v) = nil then
    MaxLength := 0
  else
    MaxLength := PDynArrayRec(NativeUInt(v) - SizeOf(TDynArrayRec)).Length;

  if CurrentLength >= MaxLength then
    SetLength(v, MaxLength + Plus);
  v[CurrentLength] := Value;
  inc(CurrentLength);
end;




Не уверен что при оптимизации это что то даст!

Но давайте заменим SetLength на реаллок!!!


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
type
  PDynArrayRec = ^TDynArrayRec;

  TDynArrayRec = packed record
{$IFDEF CPU64BITS}
    _Padding: Integer; // Make 16 byte align for payload..
{$ENDIF}
    RefCnt: Integer;
    Length: NativeInt;
  end;

  PDynArrayTypeInfo = ^TDynArrayTypeInfo;

  TDynArrayTypeInfo = packed record
    kind: TTypeKind;
    name: Byte; { string[0]; }
    elSize: Integer;
    elType: ^PDynArrayTypeInfo;
    varType: Integer;
  end;

  ArrayEx<T> = record
    v: TArray<T>;
    CurrentLength: NativeUInt;
    function add(Value: T): NativeUInt;
  end;

procedure ArrayOfPointerSetLength(ptr: PPointer; const NewLength: NativeInt);
  procedure ArrayOfPointerClear(const ptr: PPointer);
    function __DynArrayRefCnt(const A: Pointer): Integer; inline;
    begin
      Result := PDynArrayRec(PByte(A) - SizeOf(TDynArrayRec))^.RefCnt;
    end;

  var
    p: Pointer;
  begin
    p := ptr^;
    if p <> nil then
    begin
      ptr^ := nil;
      if __DynArrayRefCnt(p) > 0 then
      begin
        if AtomicDecrement(PDynArrayRec(PByte(p) - SizeOf(TDynArrayRec))
          ^.RefCnt) = 0 then
        begin
          Dec(PByte(p), SizeOf(TDynArrayRec));
          SysFreeMem(p);
        end;
      end;
    end;
  end;

const
  elSize = SizeOf(Pointer);
var
  oldLength, minLength: NativeInt;
  neededSize: NativeInt;
  p: Pointer;
begin
  p := ptr^;
  neededSize := NewLength * elSize + SizeOf(TDynArrayRec);
  if p = nil then
    p := SysAllocMem(neededSize)
  else
  begin
    Dec(PByte(p), SizeOf(TDynArrayRec));
    oldLength := PDynArrayRec(p).Length;

    if PDynArrayRec(p).RefCnt = 1 then
      p := SysReallocMem(p, neededSize)
    else
    begin
      p := SysGetMem(neededSize);
      minLength := oldLength;
      if minLength > NewLength then
        minLength := NewLength;
      Move(PByte(ptr^)^, (PByte(p) + SizeOf(TDynArrayRec))^,
        minLength * elSize);
      ArrayOfPointerClear(ptr^);
    end;
    if NewLength > oldLength then
      FillChar((PByte(p) + SizeOf(TDynArrayRec) + elSize * oldLength)^,
        elSize * (NewLength - oldLength), 0);
  end;

  PDynArrayRec(p).RefCnt := 1;
  PDynArrayRec(p).Length := NewLength;
  Inc(PByte(p), SizeOf(TDynArrayRec));

  ptr^ := p;
end;

function ArrayEx<T>.add(Value: T): NativeUInt;
const
  Plus = 16; // 32
var
  MaxLength, NewLength: Integer;
  typeInfo, pv: Pointer;
  pv2: PPointer;
begin
  if PDynArrayRec(v) = nil then
    MaxLength := 0
  else
    MaxLength := PDynArrayRec(NativeUInt(v) - SizeOf(TDynArrayRec)).Length;

  if CurrentLength >= MaxLength then
    ArrayOfPointerSetLength(Pointer(@v), MaxLength + Plus);

  v[CurrentLength] := Value;
  Inc(CurrentLength);
end;



Мне кажется,теперь эта по настоящему FAST
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762594
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что может быть легче ??? Ну если это медленно, из за использования length то давайте развратимся

Вариант 1:

Угу. Тупой вариант. Но при нем теряется целостность состава массива v. В конце будет мусор из неиспольземых элементов, что для меня неприемлемо.

Вариант 2:
Тоже самое, только через лоу-левел жопу.


В моем-же варианте я имею и возможность безопасной прямой работы с элементами массива, при этом сохраняя скорость add.
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762595
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Иными словами мой вариант при высокой скорости добавления элементов в массив сохраняет работоспособность функций Length(Array) и High(Array).
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762601
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Кхм. Странное преимущество. Когда я могу просто MyArray.CurrentLength и получить текущий размер.

rgreat В конце будет мусор из неиспольземых элементов, что для меня неприемлемо.

А ты хранишь типа, ключи к другому массиву ??? Если в другом массиве удалилось значение, то в другом это отобразится и следующий добавленный элемент встанет на место удалённого?


0.722683 секунд, при добавление 50000000 элементов

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  windows, System.SysUtils;

type
  PDynArrayRec = ^TDynArrayRec;

  TDynArrayRec = packed record
{$IFDEF CPU64BITS}
    _Padding: Integer; // Make 16 byte align for payload..
{$ENDIF}
    RefCnt: Integer;
    Length: NativeInt;
  end;

  PDynArrayTypeInfo = ^TDynArrayTypeInfo;

  TDynArrayTypeInfo = packed record
    kind: TTypeKind;
    name: Byte; { string[0]; }
    elSize: Integer;
    elType: ^PDynArrayTypeInfo;
    varType: Integer;
  end;

  ArrayEx<T> = record
    v: TArray<T>;
    CurrentLength: NativeUInt;
    function add(Value: T): NativeUInt;
  end;

procedure ArrayOfPointerSetLength(ptr: PPointer; const NewLength: NativeInt);
  procedure ArrayOfPointerClear(const ptr: PPointer);
    function __DynArrayRefCnt(const A: Pointer): Integer; inline;
    begin
      Result := PDynArrayRec(PByte(A) - SizeOf(TDynArrayRec))^.RefCnt;
    end;

  var
    p: Pointer;
  begin
    p := ptr^;
    if p <> nil then
    begin
      ptr^ := nil;
      if __DynArrayRefCnt(p) > 0 then
      begin
        if AtomicDecrement(PDynArrayRec(PByte(p) - SizeOf(TDynArrayRec))
          ^.RefCnt) = 0 then
        begin
          Dec(PByte(p), SizeOf(TDynArrayRec));
          SysFreeMem(p);
        end;
      end;
    end;
  end;

const
  elSize = SizeOf(Pointer);
var
  oldLength, minLength: NativeInt;
  neededSize: NativeInt;
  p: Pointer;
begin
  p := ptr^;
  neededSize := NewLength * elSize + SizeOf(TDynArrayRec);
  if p = nil then
    p := SysAllocMem(neededSize)
  else
  begin
    Dec(PByte(p), SizeOf(TDynArrayRec));
    oldLength := PDynArrayRec(p).Length;

    if PDynArrayRec(p).RefCnt = 1 then
      p := SysReallocMem(p, neededSize)
    else
    begin
      p := SysGetMem(neededSize);
      minLength := oldLength;
      if minLength > NewLength then
        minLength := NewLength;
      Move(PByte(ptr^)^, (PByte(p) + SizeOf(TDynArrayRec))^,
        minLength * elSize);
      ArrayOfPointerClear(ptr^);
    end;
    if NewLength > oldLength then
      FillChar((PByte(p) + SizeOf(TDynArrayRec) + elSize * oldLength)^,
        elSize * (NewLength - oldLength), 0);
  end;

  PDynArrayRec(p).RefCnt := 1;
  PDynArrayRec(p).Length := NewLength;
  Inc(PByte(p), SizeOf(TDynArrayRec));

  ptr^ := p;
end;

function ArrayEx<T>.add(Value: T): NativeUInt;
const
  Plus = 16; // 32
var
  MaxLength, NewLength: Integer;
  typeInfo, pv: Pointer;
  pv2: PPointer;
begin
  if PDynArrayRec(v) = nil then
    MaxLength := 0
  else
    MaxLength := PDynArrayRec(NativeUInt(v) - SizeOf(TDynArrayRec)).Length;

  if CurrentLength >= MaxLength then
    ArrayOfPointerSetLength(Pointer(@v), MaxLength + Plus);

  v[CurrentLength] := Value;
  Inc(CurrentLength);
end;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

var
  arr: ArrayEx<Integer>;
  i: Integer;
  T: Int64;

begin
  try
    QueryPerformanceCounter(T);

    for i := 0 to 50000000 do
      arr.add(i);

    Writeln(PrintTime(T));

    for i := 0 to 50000000 do
      if arr.v[i] <> i then
        Writeln('Faild!!: ' + i.ToString);

    Writeln('End');

    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.




Самый простой 0.9 секунд
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  windows, System.SysUtils;

type
  ArrayEx<T> = record
    v: array of T;
    CurrentLength: NativeUInt;
    function add(Value: T): NativeUInt;
  end;

function ArrayEx<T>.add(Value: T): NativeUInt;
const
  Plus = 16; // 32
var
  MaxLength: Integer;
begin
  MaxLength := Length(v);
  if CurrentLength >= MaxLength then
    SetLength(v, MaxLength + Plus);

  v[CurrentLength] := Value;
  inc(CurrentLength);
end;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

var
  arr: ArrayEx<Integer>;
  i: Integer;
  T: Int64;

begin
  try
    QueryPerformanceCounter(T);

    for i := 0 to 50000000 do
      arr.add(i);

    Writeln(PrintTime(T));

    for i := 0 to 50000000 do
      if arr.v[i] <> i then
        Writeln('Faild!!: ' + i.ToString);

    Writeln('End');

    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.




На этот Я вообще НЕ надеялся. Но если убрать length то 0.9 сек

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  windows, System.SysUtils;

type
  PDynArrayRec = ^TDynArrayRec;

  TDynArrayRec = packed record
{$IFDEF CPU64BITS}
    _Padding: Integer; // Make 16 byte align for payload..
{$ENDIF}
    RefCnt: Integer;
    Length: NativeInt;
  end;

  ArrayEx<T> = record
    v: array of T;
    CurrentLength: NativeUInt;
    function add(Value: T): NativeUInt;
  end;

function ArrayEx<T>.add(Value: T): NativeUInt;
const
  Plus = 16; // 32
var
  MaxLength: Integer;
begin
  if PDynArrayRec(v) = nil then
    MaxLength := 0
  else
    MaxLength := PDynArrayRec(NativeUInt(v) - SizeOf(TDynArrayRec)).Length;

  if CurrentLength >= MaxLength then
    SetLength(v, MaxLength + Plus);
  v[CurrentLength] := Value;
  inc(CurrentLength);
end;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

var
  arr: ArrayEx<Integer>;
  i: Integer;
  T: Int64;

begin
  try
    QueryPerformanceCounter(T);

    for i := 0 to 50000000 do
      arr.add(i);

    Writeln(PrintTime(T));

    for i := 0 to 50000000 do
      if arr.v[i] <> i then
        Writeln('Faild!!: ' + i.ToString);

    Writeln('End');

    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.




А теперь обычный TList

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  windows, System.SysUtils, classes;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

var
  arr: TList;
  i: Integer;
  T: Int64;

begin
  try
    arr := TList.Create;
    QueryPerformanceCounter(T);

    for i := 0 to 50000000 do
      arr.add(Pointer(i));

    Writeln(PrintTime(T));

    Writeln('End');

    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.



Выдал 0.724371

Короче выдумывать костыли не стоит


... Я теперь уверен что и твоя чуда магическая штука, не чуть НЕ быстрее
...
Рейтинг: 0 / 0
Список классов vs списка записей - в чем преимущество?
    #39762602
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смог выжить чуточку быстрее

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  windows, System.SysUtils;

type
  PDynArrayRec = ^TDynArrayRec;

  TDynArrayRec = packed record
{$IFDEF CPU64BITS}
    _Padding: Integer; // Make 16 byte align for payload..
{$ENDIF}
    RefCnt: Integer;
    Length: NativeInt;
  end;

  PDynArrayTypeInfo = ^TDynArrayTypeInfo;

  TDynArrayTypeInfo = packed record
    kind: TTypeKind;
    name: Byte; { string[0]; }
    elSize: Integer;
    elType: ^PDynArrayTypeInfo;
    varType: Integer;
  end;

  ArrayEx<T> = record
    v: TArray<T>;
    CurrentLength: Integer;
    procedure add(Value: T);
  end;

procedure ArrayOfPointerSetLength(ptr: PPointer; const NewLength: NativeInt);
  procedure ArrayOfPointerClear(const ptr: PPointer);
    function __DynArrayRefCnt(const A: Pointer): Integer; inline;
    begin
      Result := PDynArrayRec(PByte(A) - SizeOf(TDynArrayRec))^.RefCnt;
    end;

  var
    p: Pointer;
  begin
    p := ptr^;
    if p <> nil then
    begin
      ptr^ := nil;
      if __DynArrayRefCnt(p) > 0 then
      begin
        if AtomicDecrement(PDynArrayRec(PByte(p) - SizeOf(TDynArrayRec))
          ^.RefCnt) = 0 then
        begin
          Dec(PByte(p), SizeOf(TDynArrayRec));
          SysFreeMem(p);
        end;
      end;
    end;
  end;

const
  elSize = SizeOf(Pointer);
var
  oldLength, minLength: NativeInt;
  neededSize: NativeInt;
  p: Pointer;
begin
  p := ptr^;
  neededSize := NewLength * elSize + SizeOf(TDynArrayRec);
  if p = nil then
    p := SysAllocMem(neededSize)
  else
  begin
    Dec(PByte(p), SizeOf(TDynArrayRec));
    oldLength := PDynArrayRec(p).Length;

    if PDynArrayRec(p).RefCnt = 1 then
      p := SysReallocMem(p, neededSize)
    else
    begin
      p := SysGetMem(neededSize);
      minLength := oldLength;
      if minLength > NewLength then
        minLength := NewLength;
      Move(PByte(ptr^)^, (PByte(p) + SizeOf(TDynArrayRec))^,
        minLength * elSize);
      ArrayOfPointerClear(ptr^);
    end;
    if NewLength > oldLength then
      FillChar((PByte(p) + SizeOf(TDynArrayRec) + elSize * oldLength)^,
        elSize * (NewLength - oldLength), 0);
  end;

  PDynArrayRec(p).RefCnt := 1;
  PDynArrayRec(p).Length := NewLength;
  Inc(PByte(p), SizeOf(TDynArrayRec));

  ptr^ := p;
end;

procedure ArrayEx<T>.add(Value: T);
const
  Plus = 21; // 32
var
  MaxLength: Integer;
begin
  if PDynArrayRec(v) = nil then
    MaxLength := 0
  else
    MaxLength := PDynArrayRec(NativeUInt(v) - SizeOf(TDynArrayRec)).Length;

  if CurrentLength >= MaxLength then
    ArrayOfPointerSetLength(Pointer(@v), MaxLength + Plus);

  v[CurrentLength] := Value;
  Inc(CurrentLength);
end;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

var
  arr: ArrayEx<Integer>;
  i: Integer;
  T: Int64;

begin
  try
    QueryPerformanceCounter(T);

    for i := 0 to 50000000 do
      arr.add(i);

    Writeln(PrintTime(T));

    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.



0.616766

Почему то, самый лучший результат, если по 21 выделять элемента. Ниже или выше.. Завывают медлительность
...
Рейтинг: 0 / 0
25 сообщений из 63, страница 1 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Список классов vs списка записей - в чем преимущество?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]