You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过Boost Interprocess共享boost::variant解析后的大型逻辑表达式?

问题描述

我有多个长度可达300K的大型逻辑表达式,格式示例如下:

( ( ( 1 ) and ( 5933 or 561 or 1641 ) ) or ( ( 71 or 1 or 15 or 20 ) and ( 436 ) ) or ( ( 398 or 22 or 33 ) ) )

这些表达式用Boost Spirit解析,单条解析耗时超一分钟。我希望离线完成解析,得到以下boost::variant类型的表达式结构:

typedef boost::variant <var, 
 boost::recursive_wrapper<unop <op_not> >, 
 boost::recursive_wrapper<binop<op_and> >,
 boost::recursive_wrapper<binop<op_or> >
> expr;

需要把解析后的表达式分发到多台机器做实时计算,但这些机器无法承担初始解析耗时。我试过用unique_ptr把表达式写入Boost Interprocess的managed_mapped_file,但读取后计算时出现段错误;同时Boost序列化对超大型表达式失效,求可行方案。

可行方案

1. 自定义序列化格式(规避Boost序列化的递归/内存限制)

因为Boost序列化对超大型递归结构易出现栈溢出或内存耗尽问题,自行编写序列化逻辑更可控:

  • 遍历expr变体结构,用前缀/后缀表达式(如逆波兰式)将表达式序列化为扁平字节流:
    • 对于var类型,直接序列化变量ID(例如4字节整数)
    • 对于unop<op_not>,先写入标记位(如0x01),再序列化内部子表达式
    • 对于binop<op_and>/<op_or>,先写入对应标记位(0x02/0x03),再依次序列化左右子表达式
  • 反序列化时用栈结构还原:遇到变量压栈,遇到操作符弹出对应数量的子表达式构造节点后重新压栈,最终栈顶即为完整expr对象。
  • 该方式完全避免递归依赖,内存占用可控,适配超大型表达式场景。

2. 改用内存映射文件的结构化存储(修复段错误)

此前用unique_ptr写入managed_mapped_file出现段错误,核心原因是指针指向的内存不在共享映射区域内:

  • 所有表达式节点(var、unop、binop)必须从managed_mapped_file的内存分配器创建,不能使用默认堆内存(new/unique_ptr默认堆)
  • 定义表达式类型时,为递归包装器指定共享内存分配器:
    template<typename Op>
    struct binop {
        Op op;
        expr left;
        expr right;
    
        // 用共享内存分配器构造
        template<typename Alloc>
        binop(Op o, expr l, expr r, const Alloc& alloc)
            : op(o), left(l), right(r) {}
    };
    
  • 解析时直接在managed_mapped_file的内存空间中构建expr对象,完成后将根节点的偏移量(而非指针)写入映射文件的固定位置;其他机器读取时,通过偏移量在自身映射文件实例中定位根节点即可直接使用,避免指针失效问题。

3. 预编译表达式为字节码(极端场景最优解)

若表达式分发后逻辑固定,可将解析后的表达式转换为自定义字节码指令集:

  • 定义简单指令:例如LOAD_VAR(id)、OP_NOT、OP_AND、OP_OR
  • 遍历表达式生成字节码序列,示例表达式可生成:
    LOAD_VAR(1), LOAD_VAR(5933), LOAD_VAR(561), OP_OR, LOAD_VAR(1641), OP_OR, OP_AND,
    LOAD_VAR(71), LOAD_VAR(1), OP_OR, LOAD_VAR(15), OP_OR, LOAD_VAR(20), OP_OR, LOAD_VAR(436), OP_AND,
    OP_OR, LOAD_VAR(398), LOAD_VAR(22), OP_OR, LOAD_VAR(33), OP_OR, OP_OR
    
  • 分发时仅传输字节码数组,目标机器用轻量级字节码解释器执行计算,完全无需解析Boost Spirit表达式,也无复杂变体结构依赖,性能与兼容性拉满。

内容的提问来源于stack exchange,提问作者user1474341

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 19:55:15