2个稳定版本
3.0.1 | 2023年11月29日 |
---|
#2 in #代数表达式
270KB
3K SLoC
fasteval3
代数表达式快速且安全评估
fasteval3
是一个用于解析、编译和评估代数表达式的库。它可以直接用作计算器语言(类似于 python
),并且是构建高级语言的优秀基础。
文档
用法
将以下内容添加到您的Cargo.toml中
[dependencies]
fasteval3 = "3.0.1"
您可以使用 codegen-units=1
来获得更好的运行时性能。在某些情况下,它将大大提高LLVM的编译时优化。
如果您使用的是 'nightly' Rust编译器,您可以使用 --features nightly
来启用在 'stable' Rust中尚未提供的优化。
您可以使用 --no-default-features
来禁用如 and
、or
、NaN
、inf
等字母顺序关键字。 (这些词可能对您的应用程序很重要。)
您可以使用 --features unsafe-vars
来启用 不安全变量。
特性
- 无依赖。
- 安全执行不受信任的表达式。
- 支持稳定Rust。
- 支持解释(即解析 & 评估)以及编译执行(即解析、编译、评估)。
- 支持变量和自定义函数。
fasteval3
是构建高级语言的优秀基础。- 支持许多内置函数和常量。
- 支持所有标准的代数一元和二元运算符(+ - * / ^ %),以及比较运算符(< <= == != >= >)和逻辑运算符(&& ||)带有短路支持。
- 易于集成到各种不同类型的应用程序中,包括范围评估。
- 非常快的性能。
简单示例
这里有一个简单的示例。查看更多示例,请参阅API参考!
ez_eval()
函数为您执行整个分配-解析-评估过程。它稍微有点低效,因为它总是分配一个全新的Slab
,但它非常简单易用
fn main() -> Result<(), fasteval3::Error> {
// This example doesn't use any variables, so just use an EmptyNamespace:
let mut ns = fasteval3::EmptyNamespace;
let val = fasteval3::ez_eval(
"1+2*3/4^5%6 + log(100K) + log(e(),100) + [3*(3-3)/3] + (2<3) && 1.23", &mut ns)?;
// | | | | | | | |
// | | | | | | | boolean logic with short-circuit support
// | | | | | | comparisons
// | | | | | square-brackets act like parenthesis
// | | | | built-in constants: e(), pi()
// | | | 'log' can take an optional first 'base' argument, defaults to 10
// | | numeric literal with suffix: p, n, µ, m, K, M, G, T
// | many built-in functions: print, int, ceil, floor, abs, sign, log, round, min, max, sin, asin, ...
// standard binary operators
assert_eq!(val, 1.23);
Ok(())
}
REPL演示
github.com/OverzealousLotus/fasteval3$ rlwrap cargo run --release --example repl
Finished release [optimized] target(s) in 0.01s
Running `target/release/examples/repl`
>>> print("Hello fasteval", 1, 2, 3)
Hello fasteval 1 2 3
3
>>> _ + 1
4
>>> _ + 1
5
>>> _ * 2
10
>>> _ ^ 0.5
3.1622776601683795
>>> let a = 1
1
>>> let b = a + 1
2
>>> let c = a + b * 3
7
>>> a + b + c
10
>>> push
Entered scope[1]
>>> let b = b + 10
12
>>> a + b + c
20
>>> pop
Exited scope[1]
>>> a + b + c
10
>>> 1+2*3/4^5%6 + log(100K) + log(e(),100) + [3*(3-3)/3] + (2<3) && 1.23
1.23
>>> 1+2*3/4^5%6 + print("log(100K) =",log(100K)) + log(e(),100) + [3*(3-3)/3] + (2<3) && 1.23
log(100K) = 5
1.23
安全性
fasteval3
旨在安全地评估不受信任的表达式。默认情况下,一个表达式只能执行数学运算;它无法执行其他类型的操作(如网络、文件系统或外部命令)。此外,我们防范恶意表达式
- 过长(大于4KB)的表达式。
- 过深嵌套(大于32级)的表达式。
- 具有太多值(大于64)的表达式。
- 具有太多子表达式(大于64)的表达式。
所有限制都可以在解析时自定义。如果任何限制被超过,parse()
将返回一个错误。
请注意,您(开发者)可以定义可能执行危险操作的自定义函数。确保所有自定义功能安全是您的责任。
性能基准
注意:以下基准已经过时,是在多年前的原始项目创建期间进行的!以下是对性能基准的简要总结。对于更完整报告和分析,请参阅官方文档。
图表
请注意,以下图表使用对数刻度。因此,微小的视觉差异实际上代表非常大的性能差异。
编译表达式评估的性能
一次性解释(解析和评估)的性能
与tinyexpr C库(我们测试集中唯一支持此模式的库)相比,编译不安全变量的性能
与tinyexpr C库(我们测试集中唯一支持此模式的库)相比,解释不安全变量的性能
总结
这些结果令人印象深刻的是,fasteval3
在所有基准测试和每种操作模式(解释、编译和不安全)中始终实现了最快的时间。要声称在任何这些指标中排名第一,可以通过牺牲其他指标的性能来实现,但要创建一个全面排名第一的设计却很困难。
由于广泛的稳健性能优势,fasteval3
很可能非常适合您的动态评估需求。
许可证
fasteval3
在MIT许可证的条款下分发。
有关详细信息,请参阅LICENSE。