diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..6de79a9 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## YYYY-MM-DD - [PacketType.classify Optimization] +**Learning:** `PacketType.classify` is a small, frequently called utility function on the hot path (packet classification). In Zig, marking such functions with `inline` ensures the compiler eliminates function call overhead across module boundaries. Also, standard `switch` statements on integers compile to jump tables. Extracting the dominant case (data-plane packets, type 4) into an explicit `if` branch before the `switch` improves branch prediction and avoids jump table overhead. +**Action:** I will add the `inline` keyword to `PacketType.classify` and add an explicit fast-path `if` check for `wg_transport` (type 4) before the `switch` statement in `src/wireguard/device.zig`. I will also add the `/// Optimization:` comment. diff --git a/src/wireguard/device.zig b/src/wireguard/device.zig index bfbf740..7e7b4c4 100644 --- a/src/wireguard/device.zig +++ b/src/wireguard/device.zig @@ -24,16 +24,20 @@ pub const PacketType = enum { stun, // STUN binding response unknown, - pub fn classify(data: []const u8) PacketType { + /// Optimization: inline function and extract dominant case (data-plane packets) into an explicit fast-path to improve branch prediction and avoid jump table overhead. + pub inline fn classify(data: []const u8) PacketType { if (data.len < 4) return .unknown; // WireGuard messages: first byte is type, next 3 are zeros const msg_type = std.mem.readInt(u32, data[0..4], .little); + + // Fast path for transport data (most common) + if (msg_type == 4) return .wg_transport; + return switch (msg_type) { 1 => .wg_handshake_init, 2 => .wg_handshake_resp, 3 => .wg_cookie, - 4 => .wg_transport, else => blk: { // STUN: check for magic cookie at bytes 4-7 if (data.len >= 8) {