这个“inline for”有多少会在 Zig 的 comptime 中被缩写?

问题描述 投票:0回答:1

我正在尝试迭代

struct
的字段并根据字段的类型执行不同的操作:

const std = @import("std");

const S = struct {
    letter: u8,
    number: u64,
};

pub fn main() void {
    var result: i64 = 0;
    var s = S{ .letter = 'a', .number = 77 };
    inline for ([_][]const u8{ "letter", "number" }) |fname| {
        var v = @field(s, fname);
        switch (@TypeOf(v)) {
            u8 => result += 1,
            u64 => result += 2,
            else => unreachable,
        }
    }
    std.debug.print("result={}\n", .{result});
}

我的问题是:字段微分逻辑(

switch
)会发生在
comptime
吗?,即实际的编译程序是否会类似于

result += 1;
result += 2;

--或者会更像

const type1 = u8;
switch (type1) {
  u8 => result += 1,
  u64 => result += 2,
  else => unreachable,
}
const type2 = u64;
switch (type2) {
  u8 => result += 1,
  u64 => result += 2,
  else => unreachable,
}

我假设这些开关是不必要的,因为计算这些东西所需的一切在编译时都是已知的,但显然

switch
正在被评估,因为如果我声明
S.number
u32
,例如,执行会出现恐慌在
unreachable

如果是这种情况,我该如何重写它以使其性能更高?

metaprogramming zig
1个回答
0
投票

inline for
展开,每次迭代的代码都内联到生成的代码中进行编译。换句话说,这个

inline for (...) {
    // some code ...
}

成为

// some code ...
// some code ...

如果是这种情况,我该如何重写它以使其性能更高?

这实际上对性能没有影响,因为在发布模式下编译器会优化这段代码。例如,我使用 godbolt 检查输出程序集是否有类似代码,编译器最终将其全部减少为:

example.main:
        push    rax
        mov     rdi, rsp
        mov     qword ptr [rsp], 3
        call    "log.scoped(.default).err__anon_3359"
        pop     rax
        ret
© www.soinside.com 2019 - 2024. All rights reserved.