Enlarging SmallMutableArray#s more efficiently
resizeSmallMutableArray#
is currently implemented like this:
resizeSmallMutableArray#
:: SmallMutableArray# s a -- ^ Array to resize
-> Int# -- ^ New size of array
-> a
-- ^ Newly created slots initialized to this element.
-- Only used when array is grown.
-> State# s
-> (# State# s, SmallMutableArray# s a #)
resizeSmallMutableArray# arr0 szNew a s0 =
case getSizeofSmallMutableArray# arr0 s0 of
(# s1, szOld #) -> if isTrue# (szNew <# szOld)
then case shrinkSmallMutableArray# arr0 szNew s1 of
s2 -> (# s2, arr0 #)
else if isTrue# (szNew ># szOld)
then case newSmallArray# szNew a s1 of
(# s2, arr1 #) -> case copySmallMutableArray# arr0 0# arr1 0# szOld s2 of
s3 -> (# s3, arr1 #)
else (# s1, arr0 #)
Notably, in order to enlarge the array, a new array is allocated and initialized with a filler element (a
), and then the contents from the old one are copied over.
I have two questions about this:
-
Why isn't the initialization with the filler element skipped for length of the original array? Or are these write operations optimized away somehow?
-
Why is there no attempt to use the slop at the end of the array that results from a previous use of
shrinkSmallMutableArray#
? This should make it unnecessary to allocate a fresh array in some cases, no?