1

我是 Zig Lang 的新手,我一直在寻找 Big Int Fibonacci 的现有实现,但无济于事。

因此,我查看了 Zig Lang 的源代码,特别是Big Int Source & Big Int Tests,以弄清楚如何使用 Big Int 功能,然后提出了所需的解决方案。

这是我在学习之前尝试衡量语言速度时遵循的一种传统。就像我做的那样:Go & Rust 的 Big Int Fibonacci Benchmark。(注意,我不必为这些语言编写解决方案!)

现在,这是我在 Zig 中的实现,供您仔细阅读:

const std = @import("std");
const Managed = std.math.big.int.Managed;

pub fn main() anyerror!void {
    // var arena = std.heap.ArenaAllocator.init(std.heap.c_allocator);
    // defer arena.deinit();
    // const allocator = arena.allocator();

    const allocator = std.heap.c_allocator;

    var a = try Managed.initSet(allocator, 0);
    defer a.deinit();
    var b = try Managed.initSet(allocator, 1);
    defer b.deinit();
    var i: u128 = 0;

    while (i < 50000) : (i += 1) {
        var c = try Managed.init(allocator);

        try c.add(a.toConst(), b.toConst());

        a = b;
        b = try c.clone();

        c.deinit();
    }

    const as = try a.toString(allocator, 10, std.fmt.Case.lower);
    defer allocator.free(as);
    std.log.info("Fib: {s}", .{as});
}

如果我尝试将数字增加到 500,000,内存使用量将增加到 10 GB 以上。

我希望程序在没有内存泄漏的情况下运行 n =

    50,000 (Runs fine, with Arena & General Purpose Alloc!)
   500,000 (Mem Leak)
 1,000,000 (Mem Leak)
 5,000,000 (Mem Leak)
10,000,000 (Mem Leak)

我尝试了大多数分配器,page_allocator, ArenaAllocator, GeneralPurposeAllocator以加快进程并到达c_allocator. 至于怎么堵内存泄漏,我一点头绪都没有!

PS 我刚刚浏览了 ZigLang 和 ZigLearn 的文档以了解这一点。我没有掌握整个语言。所以请对我放轻松!

我用来构建应用程序的 PPS 命令:

zig build-exe ./src/main.zig -O ReleaseFast --strip -lc

系统信息:Mac Mini 2020,基本版本。

4

2 回答 2

3

我想出了解决方案:(使用内置交换方法进行有效的内存交换!)

const std = @import("std");
const Managed = std.math.big.int.Managed;

pub fn main() anyerror!void {
    const allocator = std.heap.c_allocator;

    var a = try Managed.initSet(allocator, 0);
    defer a.deinit();
    var b = try Managed.initSet(allocator, 1);
    defer b.deinit();
    var i: u128 = 0;

    var c = try Managed.init(allocator);
    defer c.deinit();

    while (i < 1000000) : (i += 1) {
        try c.add(a.toConst(), b.toConst());

        a.swap(&b); // This is efficient than using Clone!
        b.swap(&c); // This reduced memory leak.
    }

    const as = try a.toString(allocator, 10, std.fmt.Case.lower);
    defer allocator.free(as);
    std.log.info("Fib: {s}", .{as});
}

使用它,对于 n = 1,000,000,内存使用量最高可达 3.4 mb!

但是花了一分钟才完成,比 Rust 或 Golang 慢得多!

PS 我在 Git 上创建了一个问题:Zig 中的 Super slow Big Int Implementation

于 2022-01-19T05:12:42.613 回答
0

查看您的原始代码,您似乎a在每个循环中都有泄漏。b我认为,您需要在分配给它之前释放它。

于 2022-01-21T18:22:14.160 回答