Skip to content

Commit 1be8ddc

Browse files
committed
optimization for TBlockAllocatedArray
1 parent 1cc3406 commit 1be8ddc

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

Source/Base/Collections/Spring.Collections.Trees.pas

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ interface
4343
type
4444
TNodeColor = (Black, Red);
4545

46-
TBlockAllocatedArray<T: record> = record
46+
TBlockAllocatedArray<T> = record
4747
strict private type
4848
PT = ^T;
49+
strict private const
50+
BlockSizeBits = 6;
51+
BlockSize = 1 shl BlockSizeBits;
4952
strict private
5053
fItems: TArray<TArray<T>>;
5154
function GetItem(index: Integer): PT; inline;
@@ -506,46 +509,38 @@ implementation
506509
uses
507510
Math;
508511

509-
const
510-
BucketSize = 64;
511-
512-
513512
{$REGION 'TBlockAllocatedArray<T>'}
514513

515514
function TBlockAllocatedArray<T>.GetCapacity: Integer;
516515
begin
517-
Result := Length(fItems) * BucketSize;
516+
Result := Length(fItems) * BlockSize;
518517
end;
519518

520519
function TBlockAllocatedArray<T>.GetItem(index: Integer): PT;
521-
var
522-
row, col: Integer;
523520
begin
524-
row := index div BucketSize;
525-
col := index mod BucketSize;
526-
Result := @fItems[row, col];
521+
Result := @fItems[index shr BlockSizeBits, index and (BlockSize - 1)];
527522
end;
528523

529524
procedure TBlockAllocatedArray<T>.Grow;
525+
var
526+
n: Integer;
530527
begin
531-
SetLength(fItems, Length(fItems) + 1);
532-
SetLength(fItems[High(fItems)], BucketSize);
528+
n := Length(fItems);
529+
SetLength(fItems, n + 1);
530+
SetLength(fItems[n], BlockSize);
533531
end;
534532

535533
procedure TBlockAllocatedArray<T>.SetCapacity(const value: Integer);
536534
var
537-
oldLength: Integer;
538-
row, col: Integer;
539-
i: Integer;
535+
oldLength, newLength, i: Integer;
540536
begin
541537
oldLength := Length(fItems);
542-
row := value div BucketSize;
543-
col := value mod BucketSize;
544-
if col > 0 then
545-
Inc(row);
546-
SetLength(fItems, row);
547-
for i := oldLength to High(fItems) do
548-
SetLength(fItems[i], BucketSize);
538+
newLength := value shr BlockSizeBits;
539+
if value and (BlockSize - 1) > 0 then
540+
Inc(newLength);
541+
SetLength(fItems, newLength);
542+
for i := oldLength to newLength - 1 do
543+
SetLength(fItems[i], BlockSize);
549544
end;
550545

551546
{$ENDREGION}

0 commit comments

Comments
 (0)