std.ArrayList: initial capacity based on cache line size
also std.MultiArrayList
This commit is contained in:
@@ -181,7 +181,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
|
||||
// a new buffer and doing our own copy. With a realloc() call,
|
||||
// the allocator implementation would pointlessly copy our
|
||||
// extra capacity.
|
||||
const new_capacity = growCapacity(self.capacity, new_len);
|
||||
const new_capacity = ArrayListAlignedUnmanaged(T, alignment).growCapacity(self.capacity, new_len);
|
||||
const old_memory = self.allocatedSlice();
|
||||
if (self.allocator.remap(old_memory, new_capacity)) |new_memory| {
|
||||
self.items.ptr = new_memory.ptr;
|
||||
@@ -446,7 +446,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
|
||||
|
||||
if (self.capacity >= new_capacity) return;
|
||||
|
||||
const better_capacity = growCapacity(self.capacity, new_capacity);
|
||||
const better_capacity = ArrayListAlignedUnmanaged(T, alignment).growCapacity(self.capacity, new_capacity);
|
||||
return self.ensureTotalCapacityPrecise(better_capacity);
|
||||
}
|
||||
|
||||
@@ -1062,14 +1062,12 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
|
||||
self.capacity = 0;
|
||||
}
|
||||
|
||||
/// If the current capacity is less than `new_capacity`, this function will
|
||||
/// modify the array so that it can hold at least `new_capacity` items.
|
||||
/// 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 element pointers if additional memory is needed.
|
||||
pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
|
||||
pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void {
|
||||
if (self.capacity >= new_capacity) return;
|
||||
|
||||
const better_capacity = growCapacity(self.capacity, new_capacity);
|
||||
return self.ensureTotalCapacityPrecise(allocator, better_capacity);
|
||||
return self.ensureTotalCapacityPrecise(gpa, growCapacity(self.capacity, new_capacity));
|
||||
}
|
||||
|
||||
/// If the current capacity is less than `new_capacity`, this function will
|
||||
@@ -1218,18 +1216,20 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
|
||||
if (self.items.len == 0) return null;
|
||||
return self.getLast();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
new +|= new / 2 + 8;
|
||||
if (new >= minimum)
|
||||
return new;
|
||||
}
|
||||
const init_capacity = @as(comptime_int, @max(1, std.atomic.cache_line / @sizeOf(T)));
|
||||
|
||||
/// 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) {
|
||||
new +|= new / 2 + init_capacity;
|
||||
if (new >= minimum)
|
||||
return new;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Integer addition returning `error.OutOfMemory` on overflow.
|
||||
|
||||
Reference in New Issue
Block a user