3 ms·
It adds 65536 pointers to the binary. Alternative would be to use a hash map. I think if they made function that used inline for instead it would optimize to a
by Cloudef 2y ago
It adds 65536 pointers to the binary. Alternative would be to use a hash map. I think if they made function that used inline for instead it would optimize to a switch. No need for a LUT.
fn stringFromMsg(umsg: c_int) [:0]const u8 {
@setEvalBranchQuota(1000000);
inline for (@typeInfo(win32).Struct.decls) |field| {
if (field.name.len >= 3 and std.mem.eql(u8, field.name[0..3], "WM_")) {
if (umsg == @field(win32, field.name)) {
return field.name;
}
}
}
unreachable; // umsg is not valid, programming mistake
}
godbolt: https://zig.godbolt.org/z/7b73aoosf https://zig.godbolt.org/z/7b73aoosf
In zig-budoux, I also do comptime reflection on cImport struct to assert compile time that we won't produce broken runtime code
https://github.com/Cloudef/zig-budoux/blob/master/src/c.zig#L8-L18 https://github.com/Cloudef/zig-budoux/blob/master/src/c.zig#...
- flohofwoe 2y ago> ...instead it would optimize to a switch. No need for a LUT. IME there's is no difference in (optimized) code generation between an if-else chain, a switch or (like in your example) an unrolled for-loop with an if inside. All those high level constructs will be optimized into a single lookup table, or a combination of multiple lookup tables and binary search to select between those. Only if there are absolutely no consecutive ranges in the switch-set, a binary search without jump tables will be used.
- Cloudef 2y agoNote that you can't use normal for here as you are accessing comptime known variables. Inline for will unroll the loop so that comptime constants get resolved for testing against runtime variables and then the optimizer picks out the best code (often jump tables / switch) to generate. You are right though.