【问题标题】:Assembling a function as needed and computing it fast根据需要组装函数并快速计算
【发布时间】:2013-09-04 17:24:52
【问题描述】:

有一些解释性语言,例如 Lisp、Tcl、Perl 等,可以在运行时轻松地在代码中定义 lambda/proc/sub 并在同一会话中对其进行评估。

有一些编译语言,例如 C++,其执行速度比解释语言快得多,但在运行时在编译程序中定义一个函数并执行它并不容易,如果可能的话。

这里的问题是做到以下几点:

  1. 在运行时定义函数:例如,根据初始输入数据导出数据的分析模型。

  2. 在循环中快速执行上述函数:例如,应用派生的分析模型来分析传入的数据。

我看到的一个解决方案不是很漂亮:

  1. 在嵌入式 Tcl 中基于初始输入数据导出了表示分析模型的过程。

  2. 通过在 Tcl 中对一组样本点的过程进行评估来创建查找表,乐观地说,这些样本点将涵盖适用范围。

  3. 查找表从 Tcl 解释器传回二进制文件(用 C++ 开发)。

  4. 然后通过在查找表中“足够接近”的值之间进行插值来分析传入数据。

上述解决方案有效,但存在很多问题,无论是概念上的还是计算上的。因此问题是:是否可以纯粹在 C++ 中定义一个函数并使其可用于在同一个运行时会话中执行?

从概念上讲,是否有可能将函数创建为字符串,在内存中编译,然后以某种方式将其链接回正在执行的二进制文件?

【问题讨论】:

  • 市面上有很多高效的 Lisp 编译器。有 JIT 编译的 VM,例如 .NET 和 JVM。有可嵌入的 C 编译器(tcc、clang)。直接生成 LLVM IR 也很容易,具有强大的优化编译器的所有优点。
  • 甚至 C++ 解释器也被广泛使用,参见 CINT 和 ROOT。

标签: c++ lambda linker artificial-intelligence interpreter


【解决方案1】:

如果您想要开箱即用的东西,请查看ExprTK。如果您想自己编写表达式解析器,请查看Boost Spirit

另一种方法是动态创建 C++ 代码,将其编译为共享库(插件)并在运行时加载。这可能是最快的解决方案。

【讨论】:

  • 谢谢,乍一看,Boost Spirit 看起来很有希望。你知道它有多快吗?它是否生成了可以足够快地在循环中执行的优化二进制代码?
  • 用 Spirit 编写的解析器通常会创建一个抽象语法树 (AST),它只是操作和值的聚合。这是一个示例:Boost Spirit AST example。因此,结果通常会比优化的编译代码慢。如果速度是您最关心的问题,您应该选择最后一个建议。
  • @Michael Boost.Spirit 可以解析,但 AST 的评估将成为性能的大杀手。使用 Boost.Spirit 进行开发也需要很大的耐心,大多数编译器几乎无法处理比简单的 +/-/* 计算器样式语法更复杂的东西 - 编译时间非常长,并且必须完成各种技巧,比如破坏语法到多个文件等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
相关资源
最近更新 更多