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
相关产品推荐
相关产品推荐

