Skip to content

Instantly share code, notes, and snippets.

@maxsei
Created October 12, 2024 05:10
Show Gist options
  • Save maxsei/4faa9f9de41aaaf6e799fed91b3236a2 to your computer and use it in GitHub Desktop.
Save maxsei/4faa9f9de41aaaf6e799fed91b3236a2 to your computer and use it in GitHub Desktop.
MultiArrayList for unions does not save bytes in zig 0.13.0
$ !zig build test
test
+- run test stderr
total allocated bytes: 4608
total allocated bytes: 4672
total allocated bytes: 4672
tag type: @typeInfo(root.test_0.Foo).Union.tag_type.?
tag 0 addr: @typeInfo(root.test_0.Foo).Union.tag_type.?@7ffff7ef7200
tag 1 addr: @typeInfo(root.test_0.Foo).Union.tag_type.?@7ffff7ef7201
const std = @import("std");
const testing = std.testing;
const Allocator = std.mem.Allocator;
const CountingAllocator = struct {
child: Allocator,
count: usize = 0,
const Self = @This();
pub fn init(child: Allocator) Self {
return .{ .child = child };
}
fn alloc(ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(ctx));
const res = self.child.rawAlloc(len, ptr_align, ret_addr);
if (res != null) {
self.count += len;
}
return res;
}
fn resize(ctx: *anyopaque, buf: []u8, buf_align: u8, new_len: usize, ret_addr: usize) bool {
const self: *Self = @ptrCast(@alignCast(ctx));
if (self.child.rawResize(buf, buf_align, new_len, ret_addr)) {
self.count += new_len - buf.len;
return true;
}
return false;
}
fn free(ctx: *anyopaque, buf: []u8, buf_align: u8, ret_addr: usize) void {
const self: *Self = @ptrCast(@alignCast(ctx));
self.child.rawFree(buf, buf_align, ret_addr);
self.count -= buf.len;
}
pub fn allocator(self: *Self) Allocator {
return .{
.ptr = self,
.vtable = &.{
.alloc = alloc,
.resize = resize,
.free = free,
},
};
}
};
test {
var buf: [4 * 4096]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
const ally = fba.allocator();
const n = 64;
const Foo = union(enum) {
a: u32,
b: f64,
c: [64]u8,
};
{
var arr = try std.ArrayListUnmanaged(Foo).initCapacity(ally, n);
defer arr.deinit(ally);
for (0..n) |i| {
// try marr_list.append(ally, .{ .b = 69 });
try arr.append(ally, .{ .b = @floatFromInt(i) });
}
std.debug.print("total allocated bytes: {}\n", .{fba.end_index});
}
{
var arr = std.MultiArrayList(Foo){};
defer arr.deinit(ally);
try arr.setCapacity(ally, n);
for (0..n) |i| {
// try arr.append(ally, .{ .b = @floatFromInt(i) });
try arr.append(ally, .{ .a = @intCast(i) });
}
std.debug.print("total allocated bytes: {}\n", .{fba.end_index});
}
{
var foo = CountingAllocator.init(testing.allocator);
var arr = std.MultiArrayList(Foo){};
defer arr.deinit(foo.allocator());
for (0..n) |i| {
// try arr.append(foo.allocator(), .{ .b = @floatFromInt(i) });
try arr.append(foo.allocator(), .{ .a = @intCast(i) });
}
try arr.setCapacity(foo.allocator(), n);
std.debug.print("total allocated bytes: {}\n", .{foo.count});
const tags = arr.items(.tags);
const t = @TypeOf(tags[0]);
std.debug.print("tag type: {s}\n", .{@typeName(t)});
std.debug.print("tag 0 addr: {*}\n", .{&tags[0]});
std.debug.print("tag 1 addr: {*}\n", .{&tags[1]});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment