iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0

comptime 是 Zig 的一大特色,使用它可以將許多運算帶到編譯期,從而提高運行時的效率。這個功能類似 C++11 的 constexpr 和 C++20 的 consteval

表達式

comptime 加在表達式(Expression)前,Zig 就會將其結果在編譯期計算。如果無法在編譯期完成計算則會發出編譯期錯誤。

這邊的例子是以遞迴的方式計算費波那契數,並分成在 Run-time 和 Compile-time 計算的。使用 std.time.nanoTimestamp() 得知耗時,可以發現使用 comptime 的運行時耗時都是 0,代表它們確實在編譯期就已經完成求值。

const print = @import("std").debug.print;
const now = @import("std").time.nanoTimestamp;

fn fibonacci(index: u64) u64 {
    if (index < 2) return index;
    return fibonacci(index - 1) + fibonacci(index - 2);
}

fn run() void {
    const number = 25;

    // Run-time
    const start1 = now();
    const res1 = fibonacci(number);
    const end1 = now();

    // Compile-time
    const start2 = now();
    const res2 = comptime fibonacci(number);
    const end2 = now();

    print("Run-time:     {d} in {}ns\n", .{ res1, end1 - start1 });
    print("Compile-time: {d} in {}ns\n", .{ res2, end2 - start2 });
    print("\n", .{});
}

pub fn main() void {
    for (1..6) |_| {
        run();
    }
}
Run-time:     75025 in 1003800ns
Compile-time: 75025 in 0ns

Run-time:     75025 in 996000ns
Compile-time: 75025 in 0ns

Run-time:     75025 in 998600ns
Compile-time: 75025 in 0ns

Run-time:     75025 in 1000200ns
Compile-time: 75025 in 0ns

Run-time:     75025 in 1505500ns
Compile-time: 75025 in 0ns

泛型

泛型的型別也很適合使用 comptime 標記,以向編譯期表達此參數是編譯期就可以確定的。

const print = @import("std").debug.print;

fn add(comptime T: type, a: T, b: T) T {
    return a + b;
}

pub fn main() void {
    const res1 = add(u8, 5, 10);
    const res2 = add(f32, 100, -10);

    print("Result 1: {d}\n", .{res1});
    print("Result 2: {d}\n", .{res2});
}
Result 1: 15
Result 2: 90

參考

本文以 Zig 0.13.0 爲主。並同時發佈在:


上一篇
Zig:Hash Maps 鍵值對
下一篇
Zig:標籤 Labeled
系列文
Zig 語言入門指南——聽説你是現代化的 C30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言