2个稳定版本

3.0.1 2023年11月29日

#2 in #代数表达式

MIT 许可证

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 来禁用如 andorNaNinf 等字母顺序关键字。 (这些词可能对您的应用程序很重要。)

您可以使用 --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()将返回一个错误

请注意,您(开发者)可以定义可能执行危险操作的自定义函数。确保所有自定义功能安全是您的责任。

性能基准

注意:以下基准已经过时,是在多年前的原始项目创建期间进行的!以下是对性能基准的简要总结。对于更完整报告和分析,请参阅官方文档

图表

请注意,以下图表使用对数刻度。因此,微小的视觉差异实际上代表非常大的性能差异。

编译表达式评估的性能
Compiled Eval Performance

一次性解释(解析和评估)的性能
Interpretation Performance

与tinyexpr C库(我们测试集中唯一支持此模式的库)相比,编译不安全变量的性能
Unsafe Compiled Eval Performance

与tinyexpr C库(我们测试集中唯一支持此模式的库)相比,解释不安全变量的性能
Unsafe Interpretation Performance

总结

这些结果令人印象深刻的是,fasteval3在所有基准测试和每种操作模式(解释、编译和不安全)中始终实现了最快的时间。要声称在任何这些指标中排名第一,可以通过牺牲其他指标的性能来实现,但要创建一个全面排名第一的设计却很困难。

由于广泛的稳健性能优势,fasteval3很可能非常适合您的动态评估需求。

许可证

fasteval3在MIT许可证的条款下分发。

有关详细信息,请参阅LICENSE

没有运行时依赖

特性