从文件内容生成常量 ar 编译时间
Generating constants ar compile time from file content
假设我有一个包含一些常量的文件。此文件可能来自不同的服务,并且对于不同的场景可能有所不同。现在我想从我的程序中榨取最后一点性能,希望编译器尽可能多地进行优化,如果需要,我会为每个场景单独编译项目。
有没有办法在编译时获取一个文件,通过一些转换逻辑将它变成 Rust 代码,例如生成一些常量,并编译结果(全部在 Rust 工具中,没有其他代码生成)?
您可以只生成包含常量的 Rust 源文件。
这些部分可以是任何语言:
- 生成要用作常量的数据
- 使用一些字符串操作将它们作为常量保存到 Rust 源文件中
生锈:
pub mod const_file
在 path/to/mod.rs
use path::to::const_file::MY_CONST;
cargo build
你的 Rust 程序
您从 python:
获得的常量数组示例
array = [0, 10, 34]
const_file_str = f"pub const MY_CONST: [u16; 3] = {array};\n"
with open("path/to/const_file.rs", "w") as rust_file:
rust_file.write(const_file_str)
如果您在 crate 的根目录中写入一个 build.rs
文件,它将被编译并且 运行 每个 crate 编译。
它通常用于构建 C 绑定等,但没有什么能阻止您将它用于您自己的目的。
通常这个 build.rs
在输出目录的某处创建一个 Rust 源文件,读取 OUT_DIR
环境变量:
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=data.txt");
let out_dir = std::env::var_os("OUT_DIR").unwrap();
let path = std::path::Path::new(&out_dir).join("test.rs");
std::fs::write(&path, "pub fn test() { todo!() }").unwrap();
}
然后源代码包含在您的项目中,通常在其自己的模块中:
mod test {
include!(concat!(env!("OUT_DIR"), "/test.rs"));
}
假设我有一个包含一些常量的文件。此文件可能来自不同的服务,并且对于不同的场景可能有所不同。现在我想从我的程序中榨取最后一点性能,希望编译器尽可能多地进行优化,如果需要,我会为每个场景单独编译项目。
有没有办法在编译时获取一个文件,通过一些转换逻辑将它变成 Rust 代码,例如生成一些常量,并编译结果(全部在 Rust 工具中,没有其他代码生成)?
您可以只生成包含常量的 Rust 源文件。
这些部分可以是任何语言:
- 生成要用作常量的数据
- 使用一些字符串操作将它们作为常量保存到 Rust 源文件中
生锈:
pub mod const_file
在path/to/mod.rs
use path::to::const_file::MY_CONST;
cargo build
你的 Rust 程序
您从 python:
获得的常量数组示例array = [0, 10, 34]
const_file_str = f"pub const MY_CONST: [u16; 3] = {array};\n"
with open("path/to/const_file.rs", "w") as rust_file:
rust_file.write(const_file_str)
如果您在 crate 的根目录中写入一个 build.rs
文件,它将被编译并且 运行 每个 crate 编译。
它通常用于构建 C 绑定等,但没有什么能阻止您将它用于您自己的目的。
通常这个 build.rs
在输出目录的某处创建一个 Rust 源文件,读取 OUT_DIR
环境变量:
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=data.txt");
let out_dir = std::env::var_os("OUT_DIR").unwrap();
let path = std::path::Path::new(&out_dir).join("test.rs");
std::fs::write(&path, "pub fn test() { todo!() }").unwrap();
}
然后源代码包含在您的项目中,通常在其自己的模块中:
mod test {
include!(concat!(env!("OUT_DIR"), "/test.rs"));
}