C++ 动态构造用户定义的数学函数,以便在C+中高效调用+;?

C++ 动态构造用户定义的数学函数,以便在C+中高效调用+;?,c++,performance,function,math,dynamic,C++,Performance,Function,Math,Dynamic,示例类似于(但作为桌面应用程序)。该函数由用户以文本形式给出,因此不能在编译时编写。此外,该函数在更改之前可能会被重复使用数千次。然而,一个真实的例子是,函数的更改可能比desmos更频繁,并且它的值也可以被更多地使用 我看到了四种编写此代码的方法: 每次调用用户定义的函数时,都要使用语法分析该函数。(速度慢,函数调用多) 构造数学表达式的语法树,以便节点包含指向相应数学操作的函数指针,从而允许程序在每次调用函数时跳过对文本的解析。对于许多函数调用来说,这应该比#1快,但它仍然涉及函数指针和树,

示例类似于(但作为桌面应用程序)。该函数由用户以文本形式给出,因此不能在编译时编写。此外,该函数在更改之前可能会被重复使用数千次。然而,一个真实的例子是,函数的更改可能比desmos更频繁,并且它的值也可以被更多地使用

我看到了四种编写此代码的方法:

  • 每次调用用户定义的函数时,都要使用语法分析该函数。(速度慢,函数调用多)
  • 构造数学表达式的语法树,以便节点包含指向相应数学操作的函数指针,从而允许程序在每次调用函数时跳过对文本的解析。对于许多函数调用来说,这应该比#1快,但它仍然涉及函数指针和树,这增加了间接性,并且不像预先编译(和优化)的函数那样快
  • 使用libtcc作为动态代码生成的后端,在将用户函数翻译成C代码后快速编译,然后在主程序中使用它。因为这个编译器每秒可以在我的机器上编译大约10000个非常简单的程序,所以解析新函数几乎不会有延迟。此外,该编译器为函数生成机器代码,因此不涉及指针或树,优化由TinyCC完成。对于像我这样的中级程序员来说,这种方法更令人望而生畏
  • 编写我自己的微型编译器(不是C语言的,而是专门针对我的问题定制的),几乎可以立即生成机器代码。这可能比#3多出20倍的工作量,对未来的改进也没有多大作用(添加求和运算生成器需要我为此编写更多的汇编代码)
  • <> P>是否存在比C++ 3更容易、更平等、更有效的方法,而停留在C++领域?我对lambdas、模板和标准库没有足够的经验来确定是否有一些抽象的方法来轻松有效地编写代码

    即使是比#2快但比#3慢并且不需要动态代码生成的方法也是一种改进


    这与其说是一个现实世界的问题,不如说是一个智力上的好奇心,这就是为什么我如此关注性能,也就是为什么我不会使用其他人的数学解析库。这也是为什么我不考虑使用JavaScript或Python解释器来解释这类事情的原因。

    < P>我认为你的选项2中的一些东西是好的。除了可能更容易一点之外,使用
    float Expr::eval(std::unordered_map vars)
    方法创建一个
    Expr
    类。然后用
    名称
    实现
    Var
    Mult
    Div
    ,等等所有您想要的函数。当计算时,您只需使用like
    {{“x”,3},{“y”,4}}
    或任何东西传入映射,每个
    Expr
    对象都会将其传递给任何子表达式,然后执行其操作

    我认为这会相当快。你认为你的用户的表达会有多复杂?大多数表达式可能不需要超过10-20个函数调用

    它还可以更快地运行

    如果您试图使图形具有功能(或类似功能),如果您使操作能够处理值的向量而不是单个标量值,则可以大大加快速度


    假设你想用10000个点绘制像
    x^3-6x^2+11x-6
    这样的图形,如果你的
    Expr
    对象一次只处理单个值,是的,这就像
    ~10-15个函数调用*10000个点=大量的跳跃 ExpR< /Cord>对象可以采取数组的值,比如调用<代码> EVA/COD> > <代码> {“x”,[1,2,3…10000 ] }< /C> >这将只是<强> ~10-15函数调用,总计,进入优化C++。这可以很容易地扩展到更大数量的点,而且速度仍然非常快。

    我认为按照您的选项2的思路做一些事情会很好。除了可能更容易一点之外,使用
    float Expr::eval(std::unordered_map vars)
    方法创建一个
    Expr
    类。然后用
    名称
    实现
    Var
    Mult
    Div
    ,等等所有您想要的函数。当计算时,您只需使用like
    {{“x”,3},{“y”,4}}
    或任何东西传入映射,每个
    Expr
    对象都会将其传递给任何子表达式,然后执行其操作

    我认为这会相当快。你认为你的用户的表达会有多复杂?大多数表达式可能不需要超过10-20个函数调用

    它还可以更快地运行

    如果您试图使图形具有功能(或类似功能),如果您使操作能够处理值的向量而不是单个标量值,则可以大大加快速度

    假设你想用10000个点绘制像
    x^3-6x^2+11x-6
    这样的图形,如果你的
    Expr
    对象一次只处理单个值,是的,这就像
    ~10-15个函数调用*10000个点=大量的跳跃Expr
    对象可以采用值数组,比如使用
    {x',[1,2,3…10000]}
    调用
    eval
    ,那么这将