Skip to content

Commit 8c05c90

Browse files
vtjnashKristofferC
authored andcommitted
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 (cherry picked from commit e16dfe2)
1 parent 54a39e0 commit 8c05c90

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
@@ -1053,14 +1053,14 @@ end
10531053
# Specifically we are wasting ~10% of memory for small arrays
10541054
# by not picking memory sizes that max out a GC pool
10551055
function overallocation(maxsize)
1056-
maxsize < 8 && return 8;
1057-
# compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1056+
# compute maxsize = maxsize + 3*maxsize^(7/8) + maxsize/8
10581057
# for small n, we grow faster than O(n)
10591058
# for large n, we grow at O(n/8)
10601059
# and as we reach O(memory) for memory>>1MB,
10611060
# this means we end by adding about 10% of memory each time
1061+
# most commonly, this will take steps of 0-3-9-34 or 1-4-16-66 or 2-8-33
10621062
exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
1063-
maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
1063+
maxsize += (1 << div(exp2 * 7, 8)) * 3 + div(maxsize, 8)
10641064
return maxsize
10651065
end
10661066

test/arrayops.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,12 @@ end
519519
v = empty!(collect(1:100))
520520
pushfirst!(v, 1)
521521
@test length(v.ref.mem) == 100
522+
523+
# test that insert! at position 1 doesn't allocate for empty arrays with capacity (issue #58640)
524+
v = empty!(Vector{Int}(undef, 5))
525+
insert!(v, 1, 10)
526+
@test v == [10]
527+
@test length(v.ref.mem) == 5
522528
end
523529

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

test/core.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6830,9 +6830,6 @@ Base._growat!(A, 4, 1)
68306830
Base._growat!(A, 2, 3)
68316831
@test getindex(A, 1) === 0x01
68326832
@test getindex(A, 2) === missing
6833-
@test getindex(A, 3) === missing
6834-
@test getindex(A, 4) === missing
6835-
@test getindex(A, 5) === missing
68366833
@test getindex(A, 6) === 0x03
68376834
@test getindex(A, 7) === missing
68386835
@test getindex(A, 8) === missing

0 commit comments

Comments
 (0)