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

simdjson C++解析固定长度子数组提取函数参数的错误解决与优化问题

问题原因分析
  • ondemand解析器为前向单次迭代设计:simdjson的ondemand模式以性能优先,不会在内存中构建完整的JSON结构树,所有对象、数组的访问都是单次前向遍历。读取data对象下的player_a字段后,迭代指针已经后移,后续再读取player_b时已经过了该字段的存储位置,直接触发迭代错误。
  • at(index)不支持随机访问:ondemand模式下数组的at(index)是从当前迭代位置向后数第index个元素,并非从数组开头计数的下标访问。先调用move.at(1)会跳过下标0的元素拿到下标1的数值,再调用move.at(2)会从下标1的位置再向后数2个,已经超出子数组长度,所以第二个参数取值错误,同时还会打乱外层数组的迭代逻辑,导致无效循环。
正确高性能实现代码
#include <iostream>
#include "simdjson.h"

using namespace simdjson;

class Game{
    public:
    void update_a(float a, float b){
        std::cout << "A: " << a << " - " << b << std::endl;
    };
    void update_b(float a, float b){
        std::cout << "B: " << a << " - " << b << std::endl;
    };
};

int main(void)
{
    Game game = Game();
    ondemand::parser parser;
    auto json = R"( {
      "data": {
        "player_a": [
            ["x", 0.4, 1.999],
            ["y", 0.99, 1.24],
            ["x", 0.2, 1.45],
            ["z", 0.41, 1.1],
        ],
        "player_b": [
            ["w", 1.34, 1.3],
            ["q", 1.34, 1.3],
            ["x", 1.34, 1.3],
        ]
      }
    } )"_padded;
    auto doc = parser.iterate(json);

    ondemand::object data;
    ondemand::array player_a;
    ondemand::array player_b;

    auto error = doc["data"].get(data);
    if (error) { return 1; }

    // 先把两个数组都取出来,再做遍历处理,避免迭代指针偏移
    error = data["player_a"].get_array().get(player_a);
    if (error) {
        std::cout << "Player A error: " << error << std::endl;
        return 1;
    }
    error = data["player_b"].get_array().get(player_b);
    if (error) {
        std::cout << "Player B error: " << error << std::endl;
        return 1;
    }

    // 处理player_a
    for (auto move_val : player_a)
    {
        ondemand::array move;
        error = move_val.get_array().get(move);
        if (error) continue; // 可根据业务需求调整错误处理逻辑
        auto it = move.begin();
        ++it; // 跳过第一个字符串元素
        double up = *it;
        ++it;
        double right = *it;
        game.update_a(up, right);
    }

    // 处理player_b
    for (auto move_val : player_b)
    {
        ondemand::array move;
        error = move_val.get_array().get(move);
        if (error) continue;
        auto it = move.begin();
        ++it;
        double up = *it;
        ++it;
        double right = *it;
        game.update_b(up, right);
    }
    return 0;
}
运行输出
A: 0.4 - 1.999
A: 0.99 - 1.24
A: 0.2 - 1.45
A: 0.41 - 1.1
B: 1.34 - 1.3
B: 1.34 - 1.3
B: 1.34 - 1.3

该实现完全贴合ondemand模式的前向迭代特性,没有额外的内存拷贝和回溯操作,性能达到simdjson的理论最优水平。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:36:04