【问题标题】:Java - Efficient evaluation of user-input math functions (preparation possible, existing variables)Java - 用户输入数学函数的有效评估(准备可能,现有变量)
【发布时间】:2016-06-10 16:04:21
【问题描述】:

在具有变量 t 计算时间(相对于程序启动,而不是系统时间)的 Java 程序中,如何将用户输入的字符串转换为可以在需要时有效评估的数学公式。 (基本上,公式的准备可能会很慢,因为它发生在运行前,但每个存储的函数可能在运行时被调用多次,然后必须有效地评估)

由于我找不到一个可以加载公式以供以后参考的数学解析器,而不是找到求解 y=f(x) 方程的通用图,因此我正在考虑让我的 Java 程序生成一个脚本 ( JS、Python 等)从输入字符串中取出,然后以当前 t 作为输入参数调用所述脚本。 - 但是有人告诉我,脚本相当慢,因此对于实时应用程序来说是不切实际的。

有没有更有效的方法来做到这一点? (如果可行的话,我什至会考虑让我的 Java 应用程序为每个用户输入生成和编译 C 代码)

编辑:树结构确实可以存储表达式,但评估仍然相当慢,因为据我了解,在评估时(如遍历树对象),我需要再次将其转换为表达式链应该比直接求解方程需要更多的调用。相反,我将尝试生成额外的 java 类。

【问题讨论】:

  • 高效或“多次”是什么意思?如果你有一个用 Java 编写的函数,它只会在默认情况下被调用 10,000 次后编译为本机代码。所以你说的不止这些吗?
  • 一个旧的且在 ODE 可视化小程序staff.science.uu.nl/~beuke106/phase/newphase.html 中经过良好测试的解析器是 D. Bacon 的 expr 包,可在 wry.me/~darius 下找到
  • @PeterLawrey 链接到的“非常简化”版本也可以在this answer 中找到。但请注意,为了使用集成的JavaCompiler,程序必须使用 JDK 运行。 JRE 是不够的,因为它不包含 tools.jar)

标签: java performance math processing-efficiency


【解决方案1】:

我所做的是在运行时生成 Java 代码并编译它。有许多库可以帮助您做到这一点,我写的一个是 https://github.com/OpenHFT/Java-Runtime-Compiler 这样它就可以像您自己手写 Java 代码一样高效,并且如果调用足够多次将被编译为本机代码。

【讨论】:

    【解决方案2】:

    您能否提供一些关于假定功能类型和要求性能的信息?也许只使用数学解析器库就足够了,它只预编译包含带有变量的数学公式的字符串一次,然后即使变量值发生变化,也使用这种预编译形式的公式来提供结果?这种解决方案非常快,因为它通常不需要重复的字符串解析、语法检查等。

    我最近在我的项目中使用的这种开源数学解析器的一个例子是 mXparser:

    mXparser on GitHub

    http://mathparser.org/

    包含函数定义的使用示例

    Function f = new Function("f(x,y) = sin(x) + cos(y)");
    double v1 = f.calculate(1,2);
    double v2 = f.calculate(3,4);
    double v3 = f.calculate(5,6);
    

    在上面的代码中,真正的字符串解析将只进行一次,在计算 v1 之前。进一步计算 v1、v2(可能的 vn)将在快速模式下完成。

    另外你可以在字符串表达式中使用函数定义

    Expression e = new Expression("f(1,2)+f(3,4)", f);
    double v = e.calculate();
    

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 2020-04-06
      • 2015-07-05
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      相关资源
      最近更新 更多