Multi-Object For Loops + Struct-Of-Arrays
source link: https://zig.news/andrewrk/multi-object-for-loops-data-oriented-design-41ob
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Now that the new for loop syntax has landed, there is a pretty cool combination you can do with for loops and std.MultiArrayList
:
const std = @import("std");
const S = struct {
tag: u8,
data: u32,
};
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const arena = arena_instance.allocator();
var list: std.MultiArrayList(S) = .{};
try list.append(arena, .{ .tag = 42, .data = 99999999 });
try list.append(arena, .{ .tag = 10, .data = 1231011 });
try list.append(arena, .{ .tag = 69, .data = 1337 });
try list.append(arena, .{ .tag = 1, .data = 1 });
for (list.items(.tag), list.items(.data)) |tag, data| {
std.debug.print("tag = {d}, data = {d}\n", .{ tag, data });
}
}
Output:
$ zig run test.zig
tag = 42, data = 99999999
tag = 10, data = 1231011
tag = 69, data = 1337
tag = 1, data = 1
I'll further augment it with some sorting because I think the API is pretty dang cool:
const std = @import("std");
const S = struct {
tag: u8,
data: u32,
};
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const arena = arena_instance.allocator();
var list: std.MultiArrayList(S) = .{};
try list.append(arena, .{ .tag = 42, .data = 99999999 });
try list.append(arena, .{ .tag = 10, .data = 1231011 });
try list.append(arena, .{ .tag = 69, .data = 1337 });
try list.append(arena, .{ .tag = 1, .data = 1 });
const TagSort = struct {
tags: []const u8,
pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
return ctx.tags[lhs_index] < ctx.tags[rhs_index];
}
};
list.sort(TagSort{ .tags = list.items(.tag) });
for (list.items(.tag), list.items(.data)) |tag, data| {
std.debug.print("tag = {d}, data = {d}\n", .{ tag, data });
}
}
Output:
$ zig run test.zig
tag = 1, data = 1
tag = 10, data = 1231011
tag = 42, data = 99999999
tag = 69, data = 1337
The key thing to note here is that, in these examples there are two arrays, one for tag
and one for data
. These examples demonstrate Zig's ability to manipulate struct-of-arrays with ease.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK