Skip to content

Commit e16dfe2

Browse files
authored
array: avoid overallocation when inserting at beginning of empty arrays (#59717)
Fixes a minor nuisance where length 0 would grow to 8 and length 7 would also grow to 8. Instead growing by a flat 3x even initially. Fixes #58640
1 parent 05c07e1 commit e16dfe2

File tree

3 files changed

+9
-6
lines changed

3 files changed

+9
-6
lines changed

base/array.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,14 +1087,14 @@ end
10871087
# Specifically we are wasting ~10% of memory for small arrays
10881088
# by not picking memory sizes that max out a GC pool
10891089
function overallocation(maxsize)
1090-
maxsize < 8 && return 8;
1091-
# compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1090+
# compute maxsize = maxsize + 3*maxsize^(7/8) + maxsize/8
10921091
# for small n, we grow faster than O(n)
10931092
# for large n, we grow at O(n/8)
10941093
# and as we reach O(memory) for memory>>1MB,
10951094
# this means we end by adding about 10% of memory each time
1095+
# most commonly, this will take steps of 0-3-9-34 or 1-4-16-66 or 2-8-33
10961096
exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
1097-
maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
1097+
maxsize += (1 << div(exp2 * 7, 8)) * 3 + div(maxsize, 8)
10981098
return maxsize
10991099
end
11001100

test/arrayops.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,12 @@ end
525525
v = empty!(collect(1:100))
526526
pushfirst!(v, 1)
527527
@test length(v.ref.mem) == 100
528+
529+
# test that insert! at position 1 doesn't allocate for empty arrays with capacity (issue #58640)
530+
v = empty!(Vector{Int}(undef, 5))
531+
insert!(v, 1, 10)
532+
@test v == [10]
533+
@test length(v.ref.mem) == 5
528534
end
529535

530536
@testset "popat!(::Vector, i, [default])" begin

test/core.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6852,9 +6852,6 @@ Base._growat!(A, 4, 1)
68526852
Base._growat!(A, 2, 3)
68536853
@test getindex(A, 1) === 0x01
68546854
@test getindex(A, 2) === missing
6855-
@test getindex(A, 3) === missing
6856-
@test getindex(A, 4) === missing
6857-
@test getindex(A, 5) === missing
68586855
@test getindex(A, 6) === 0x03
68596856
@test getindex(A, 7) === missing
68606857
@test getindex(A, 8) === missing

0 commit comments

Comments
 (0)