Closed miroslavp closed 1 year ago
LOL, I just realized that we don't need to copy/clone those arrays at all https://github.com/Wsm2110/Faster.Map/blob/9c60000c53e0bad32b9130a5b3297ec9f259e4d2/src/DenseMapSIMD.cs#L759-L763 We don't use them anymore. Right on the next line we erase the variables. So we can just copy the references
var oldEntries = _entries;
var oldMetadata = _metadata;
_metadata = new sbyte[_length + 16];
_entries = new Entry<TKey, TValue>[_length + 16];
My suggestion in the previous comment still stands though :)
hi mate, love these suggestions. Keep'em coming
This is a bit bold, but works nice for your algorithm. It is up to you if you want to amend it or not. I have noticed that after the allocation of the new metadata array, you immediately initialize it with the emptyBucket value (-127). So basically the array is initialized twice - once with zeros (using
new
) and then with -127. Also, the entries array is never used in the code without first checking the metadata array (well, except for the IndexOf() method which is for testing purposes, but it also can be amended to make metadata lookups first)https://github.com/Wsm2110/Faster.Map/blob/9c60000c53e0bad32b9130a5b3297ec9f259e4d2/src/DenseMapSIMD.cs#L762-L765
So basically we can safely allocate both arrays without initializing them to zero (you don't rely on those zeros in the code anyway) using
GC.AllocateUninitializedArray
. I have tested it and allocation of array of 1_000_000 ints without initialization is about 11 times faster.This brings also slight improvement to the final AddAndResize benchmark. Let me know what you think!
P.S. If you don't like that the following line starts with
new
new Span<sbyte>(_metadata).Fill(_emptyBucket);
the following is equivalent_metadata.AsSpan().Fill(_emptyBucket);