Open arBmind opened 2 years ago
@marler8997 Thank you for considering my PR.
My first commit made it work, without any changes. My second commit requires this PR https://github.com/marlersoft/win32jsongen/pull/4 for win32jsongen to work properly. This adds curly braces to the GUIDs in the JSON files.
Ok, well the commit I added should also work, it just adds the curly braces when generating the code. However it's still making my zig test zigwin32\win32.zig
take much longer but I'm not sure why (like 100 times longer, around 45 seconds compared to it's still running after 20 minutes or so). I created a small test app to see if std
GUID was slower at comptime but I didn't see much difference. Will have to investigate more.
Here's the perf test app for reference:
const builtin = @import("builtin");
const std = @import("std");
pub fn main() void {
comptime {
const count = 1000000;
@setEvalBranchQuota(count * 3);
var i: usize = 0;
while (i < count) : (i += 1) {
//_ = std.os.windows.GUID.parse("{aa7a8931-80e4-4fec-8f3b-553f87b4966e}");
_ = Guid.parse("aa7a8931-80e4-4fec-8f3b-553f87b4966e");
}
}
}
// TODO: this should probably be in the standard lib somewhere?
pub const Guid = extern union {
Ints: extern struct {
a: u32,
b: u16,
c: u16,
d: [8]u8,
},
Bytes: [16]u8,
const big_endian_hex_offsets = [16] u6 {0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34};
const little_endian_hex_offsets = [16] u6 {
6, 4, 2, 0,
11, 9,
16, 14,
19, 21, 24, 26, 28, 30, 32, 34};
const hex_offsets = switch (builtin.target.cpu.arch.endian()) {
.Big => big_endian_hex_offsets,
.Little => little_endian_hex_offsets,
};
pub fn parse(s: []const u8) Guid {
var guid = Guid { .Bytes = undefined };
for (hex_offsets) |hex_offset, i| {
//guid.Bytes[i] = decodeHexByte(s[offset..offset+2]);
guid.Bytes[i] = decodeHexByte([2]u8 { s[hex_offset], s[hex_offset+1] });
}
return guid;
}
};
comptime { std.debug.assert(@sizeOf(Guid) == 16); }
// TODO: is this in the standard lib somewhere?
fn hexVal(c: u8) u4 {
if (c <= '9') return @intCast(u4, c - '0');
if (c >= 'a') return @intCast(u4, c + 10 - 'a');
return @intCast(u4, c + 10 - 'A');
}
// TODO: is this in the standard lib somewhere?
fn decodeHexByte(hex: [2]u8) u8 {
return @intCast(u8, hexVal(hex[0])) << 4 | hexVal(hex[1]);
}
Ok I've grepped all of zigwin32
for all the Guids and put them into a single file to test performance (see https://gist.github.com/marler8997/2ab2fc12190792308d233efcafe89ac3). My custom Guid takes about 12
seconds to run zig test guids.zig
, the one from std.os.windows
takes about 6 minutes! To see for yourself, change the variable use_std_guid
in the gist above to test the performance of each one.
I've submitted a PR to create a benchmark for GUID.parse
here: https://github.com/ziglang/gotta-go-fast/pull/21
Once that's in I'll see about replacing the implementation in std
with the one here, then we could switch to it.
Your branch made me realize that I should have been importing
Guid
instead of referencing its fully-qualified name each time. I pushed a commit that fixed that here: 449b7cd15244b6c652287e5321529fbbeb8b65d1I rebased your commits and added an additional one that removes
Guid
completely fromzig.zig
and updates all references to use the one fromstd
directly.For some reason this this is causing
zig test zigwin32\win32.zig
to take forever for me...