Skip to content

Commit

Permalink
significantly increase speed of random array access operations
Browse files Browse the repository at this point in the history
  • Loading branch information
nilproject committed Dec 17, 2024
1 parent 249c6f5 commit 2d5bb17
Showing 1 changed file with 44 additions and 16 deletions.
60 changes: 44 additions & 16 deletions NiL.JS/Core/SparseArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public override string ToString()
}
}

private const int SegmentSize = 16384;
private const int SegmentSize = 1024;

private static TValue _fictive;

Expand Down Expand Up @@ -145,9 +145,13 @@ internal ref TValue TryGetInternalForWrite(uint index, out bool got)

if (itemIndex >= values.Length)
{
if (itemIndex <= values.Length + 4)
if (itemIndex <= values.Length + 4 || values.Length * 4 >= SegmentSize)
{
Array.Resize(ref values, Math.Min(SegmentSize, Math.Max(values.Length * 2, 8)));
var newSize = Math.Min(SegmentSize, Math.Max(values.Length * 2, 8));
if (newSize <= itemIndex)
newSize *= 2;

Array.Resize(ref values, newSize);

_values[realSegmentIndex] = values;
}
Expand Down Expand Up @@ -220,10 +224,8 @@ private void resizeL0(int newRealSegmentsCount)
Array.Resize(ref _used, _navyData.Length);

for (var i = _navyData.Length - 1; i >= 0 && _navyData[i] is null; i--)
_navyData[i] = [];

for (var i = _values.Length - 1; i >= 0 && _values[i] is null; i--)
{
_navyData[i] = [];
_values[i] = [];
}
}
Expand Down Expand Up @@ -302,7 +304,7 @@ private enum FindNearestMode { NotLess, NotMore }
}
}
}

if (firstTry)
{
firstTry = false;
Expand Down Expand Up @@ -395,7 +397,7 @@ private enum FindNearestMode { NotLess, NotMore }
}
}
}

if (firstTry)
{
firstTry = false;
Expand Down Expand Up @@ -592,19 +594,42 @@ private ref TValue getFromTree(uint index, bool forRead, out bool got, int realS
else
navyItem.zeroNext = ni;

got = true;

if (ni >= navy.Length)
{
var newSize = ni * 2;

Array.Resize(ref _navyData[realSegmentIndex], newSize);
Array.Resize(ref _values[realSegmentIndex], newSize);
if (newSize * 2 >= SegmentSize)
{
values = new TValue[SegmentSize];

navy = _navyData[realSegmentIndex];
for (var n = 0; n < navy.Length; n++)
{
var relativeIndex = navy[n].index & (SegmentSize - 1);
if (relativeIndex == 0 && n != 0)
break;

values[relativeIndex] = _values[realSegmentIndex][n];
}

_values[realSegmentIndex] = values;
_navyData[realSegmentIndex] = [];

return ref values[index & (SegmentSize - 1)];
}
else
{
Array.Resize(ref navy, newSize);
Array.Resize(ref values, newSize);

navy = _navyData[realSegmentIndex];
values = _values[realSegmentIndex];
_navyData[realSegmentIndex] = navy;
_values[realSegmentIndex] = values;
}
}

navy[ni].index = index;
got = true;
return ref values[ni];
}

Expand All @@ -624,14 +649,17 @@ private ref TValue getFromTree(uint index, bool forRead, out bool got, int realS
var oldValue = values[i];

navyItem.index = index;
values[i] = default!;

if (oldIndex < _pseudoLength)
this[(int)oldIndex] = oldValue!;

values = _values[realSegmentIndex];
values[i] = default!;

got = true;

if (_navyData[realSegmentIndex].Length == 0)
i = (int)(index & (SegmentSize - 1));

values = _values[realSegmentIndex];
return ref values[i];
}
else
Expand Down

0 comments on commit 2d5bb17

Please sign in to comment.