为什么 Rust 的 .rlib 通常比 C 的 .o 文件大?
结论
这组数据不足以证明 Rust 生成的机器码约为 C 的 4 倍。你比较的是 Rust 的 .rlib 库归档和 C 的 .o 目标文件,两者包含的内容不同,编译命令使用的优化设置也不一致。
为什么这两个文件大小不同
--crate-type lib 生成的是 Rust 库产物 .rlib。它通常是一个归档文件,除了目标代码,还可能包含 Rust 编译所需的元数据,以及根据编译配置生成的其他内容。实际包含哪些成员,可以检查文件确认。
gcc -c 生成的是单个 C 目标文件 .o,还没有经过链接。它包含目标文件格式所需的节、符号表等信息,但与 .rlib 不是同一种产物。
所以,即使两段函数逻辑都只是整数相加,容器格式和编译器生成的附加信息也会影响文件大小。仅凭 5248 字节和 1288 字节,无法判断差异主要来自哪一部分,也不能据此断定 Rust 机器码更大。
示例中没有将 Rust 标准库静态链接进最终程序:它使用了 #![no_std],并将 crate 编译为库,没有执行最终链接。因此,标准库静态链接的解释不适用于这两个文件的直接对比。
如何检查 .rlib 的内容
先查看归档中的成员,再检查其中的目标文件和节:
ar t libsimple_rust.rlib
要继续检查某个成员,可以将 .rlib 解压到单独目录,再用 readelf -S 或 objdump -h 查看节,用 nm 查看符号。这样可以区分目标代码、元数据及其他占用,而不必从归档总大小推测原因。
怎样做更公平的比较
先统一比较对象:可以比较两边各自的目标文件,也可以分别构建库归档后比较。如果关心最终程序,则应比较完成链接后的可执行文件。编译时也要尽量统一目标平台和优化目标。例如,Rust 使用了 -C opt-level="z",而给出的 GCC 命令没有指定优化选项,因此这组结果是在不同优化条件下得出的。
Rust 和 GCC 的优化选项不保证产生完全相同的优化行为。即使选用面向体积的选项,最终大小仍取决于编译器、目标平台、调试信息、链接方式及是否剥离符号等因素。要判断这次差异具体来自哪里,可以检查归档成员和节,并在统一条件下重新构建后比较。
备注:内容仅供参考。
