aboutsummaryrefslogtreecommitdiff
path: root/lib/std/multi_array_list.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-02-11 18:53:13 -0800
committerAndrew Kelley <andrew@ziglang.org>2025-02-13 00:19:03 -0800
commitd12123a88cf56428874b359cb63acb8618dfbcfd (patch)
treecb4798e72f47d303d5ac527467b021f467c86818 /lib/std/multi_array_list.zig
parent5b9b5e45cb710ddaad1a97813d1619755eb35a98 (diff)
downloadzig-d12123a88cf56428874b359cb63acb8618dfbcfd.tar.gz
zig-d12123a88cf56428874b359cb63acb8618dfbcfd.zip
std.ArrayList: initial capacity based on cache line size
also std.MultiArrayList
Diffstat (limited to 'lib/std/multi_array_list.zig')
-rw-r--r--lib/std/multi_array_list.zig28
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig
index 44eea7d57e..7d68322c90 100644
--- a/lib/std/multi_array_list.zig
+++ b/lib/std/multi_array_list.zig
@@ -405,17 +405,27 @@ pub fn MultiArrayList(comptime T: type) type {
/// Modify the array so that it can hold at least `new_capacity` items.
/// Implements super-linear growth to achieve amortized O(1) append operations.
- /// Invalidates pointers if additional memory is needed.
- pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) !void {
- var better_capacity = self.capacity;
- if (better_capacity >= new_capacity) return;
+ /// Invalidates element pointers if additional memory is needed.
+ pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void {
+ if (self.capacity >= new_capacity) return;
+ return self.setCapacity(gpa, growCapacity(self.capacity, new_capacity));
+ }
+
+ const init_capacity = init: {
+ var max = 1;
+ for (fields) |field| max = @as(comptime_int, @max(max, @sizeOf(field.type)));
+ break :init @as(comptime_int, @max(1, std.atomic.cache_line / max));
+ };
+ /// Called when memory growth is necessary. Returns a capacity larger than
+ /// minimum that grows super-linearly.
+ fn growCapacity(current: usize, minimum: usize) usize {
+ var new = current;
while (true) {
- better_capacity += better_capacity / 2 + 8;
- if (better_capacity >= new_capacity) break;
+ new +|= new / 2 + init_capacity;
+ if (new >= minimum)
+ return new;
}
-
- return self.setCapacity(gpa, better_capacity);
}
/// Modify the array so that it can hold at least `additional_count` **more** items.
@@ -838,7 +848,7 @@ test "union" {
try testing.expectEqual(@as(usize, 0), list.items(.tags).len);
- try list.ensureTotalCapacity(ally, 2);
+ try list.ensureTotalCapacity(ally, 3);
list.appendAssumeCapacity(.{ .a = 1 });
list.appendAssumeCapacity(.{ .b = "zigzag" });