开发者生态
morning
Goose:实验性语言比 C++ 快 1.16 倍,比安全 Rust 快 1.12 倍,内存安全
摘要
The Goose Programming Language A memory-safe systems language that is faster than C++ and Rust, on less memory, with no allocator/GC and no lifetime annotations. Tutorial · Specification · Samples · B...
and
the
safe
that
Rust
memory
than
one
The
Goose
2026-09-18
1 阅读
约6分钟阅读
bobbydigitales
字号:
Goose 编程语言 一种内存安全的系统语言,比 C++ 和 Rust 更快,内存更少,没有分配器/GC,也没有生命周期注释。教程 · 规范 · 示例 · 基准 · 标准库 Goose 看起来像 C 或 Rust 一样熟悉,并且建立在一个想法之上:没有堆。每个动态值都内联地存在于编译器管理的数据堆栈上,增长是指针碰撞,作用域退出是唯一自由的。该语言的其余部分是使其适用于实际程序所需的内容,并且它所购买的内容是可衡量的。比 C++ 更快,比 Rust 更安全,同时内存安全。在超过 16 个基准测试中,Goose 的运行速度是惯用 C++ 的 3.3 倍、手动优化的 C++ 的 1.16 倍、最佳安全 Rust 的 1.12 倍,内存减少了 1.9 倍、1.3 倍和 1.2 倍(摘要、完整结果)。胜利是结构性的:它们来自其他语言无法表达的东西。没有分配器,没有GC,没有引用计数,没有析构函数。内存是编译器静态分配的少量数据堆栈。释放一百万个元素的结构就是一个存储,无论它嵌套得有多深。什么都没有动过。只要数组存在,对不断增长的数组的引用就保持有效。您可以在 C++ 必须保留的地方保留类型化引用,并安全地将 Rust 退回到 u32 索引。内存安全,零注释。没有生命周期语法,没有别名或排他性规则,没有 unsafe 。编译器推断出每个引用的根源,并指向一件事:比所有者寿命更长。一路向下都是平的。字符串、字符串数组、具有可变大小字段的记录以及这些记录的数组都是一个连续的块,其中没有指针。一条记录为 160 字节,C++ 中的分配为 29 字节,而 Goose 中则没有。枚举花费了它们所持有的内容。变量模式 ADT 为每个值提供其自己的变体大小,而不是最大的大小:在执行它的基准测试中,内存减少 4 倍,速度是 Rust 枚举的 2 倍。链接比指针窄。相对引用将类型化、检查过的链接存储为 1、2 或 4 字节偏移量。从它们构建的结构是位置无关的,因此您的数据结构已经是它的文件格式:保存是写入,加载是读取加上拒绝敌对字节的验证通过。一切都已就位,有保证。通过任何深度的调用,在其最终目的地构造一个值。 items.push(parse(line)) 将解析后的记录直接写入数组,并且按值返回可增长的数组不需要任何成本。没有管道的错误。 return err from load 从函数返回任意数量的帧,静态检查,没有展开器,没有结果类型,也没有 ?每次通话时。不共享任何内容的线程。工作线程被编译为具有自己的内存的单独程序,并且平面值作为 memcpy 跨类型队列。该语言中不存在数据竞争、锁、原子和内存排序。泛型和高阶函数没有开销。无类型参数是通用的。函数值是编译时实体,因此 xs.filter() { it > 0 } 编译为看起来像的循环,并将其结果直接构建到目标中。纯 C 输入,纯 C 输出。 Goose 编译为一个 C 文件,因此它可以在 C 编译器所在的任何地方运行,并通过 extern fn 直接调用 C。捆绑的 TinyCC 后端在进程中编译并运行程序,无需构建步骤。本教程通过示例介绍了所有这些,规范有确切的规则,基准测试有数字,包括损失。这里只展示了 Goose 的不同之处。本教程正确地涵盖了相同的基础,并且示例是二十六个完整的程序,它们是真实执行的。一种内存模型:堆栈,作用域出口是空闲的 程序具有本机调用堆栈、静态数据和 N 个数据堆栈,编译器在其中计算出 N 个数据堆栈。数据堆栈是带有凹凸指针的大地址空间保留,并且没有其他内存。每个堆栈最多有一个可调整大小的值,并且它始终位于顶部,因此增长永远不会移动任何内容,也不会检查容量。所有这些都在编译时得到证明;运行时只保留凹凸指针。 for round in 3 { var scrap: u8[>..] = []; // 仅增长:增长是 i 在 100000 中的指针碰撞 { scrap.push((i % 256) as! u8); } print("round", round, ":", scrap.len, "bytes"); } // free: 一次存储到栈顶 没有任何内容移动,因此引用会继续增长 struct Item { id: i32, Weight: f32 } var items: Item[>..] = [];首先让 .= items.push(Item { 1, 0.5 }); // 对元素 0 的引用 for i in 2..1000001 { items.push(Item { i as i32, 0.0 });第一个.权重 = 99.5; // 仍然有效,一百万次推送后推送返回对其刚刚创建的元素的引用,这就是数据在构建时链接起来的方式。 Vector 或 Vec 会重新分配,因此两者都不能保证这一点,而这正是基准测试胜利的大部分来源。安全引用,无注释每个引用和切片都带有一个静态根,即限制 i 的变量
这篇文章对您有帮助吗?
订阅66必读
每日精选科技资讯,直达你的邮箱