mirror of
https://github.com/nlohmann/json.git
synced 2026-10-22 14:08:13 +00:00
* Flatten into a std::map by inserting next to the previous entry flatten() added every path with operator[], so each insertion into the std::map of the result searched the tree from the root and compared long shared path prefixes, which took half the time on canada.json. Paths come out in nearly sorted order, so they are now inserted with emplace_hint next to the entry added last, for object types that have it. ordered_map keeps its append without lookup, and other object types keep operator[]. Path segments are also appended in place, without a temporary string for each escaped key or array index. flatten() of canada.json, citm_catalog.json and twitter.json is 1.4x to 1.9x as fast; ordered_json is unchanged (1.05x). The output is unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Unflatten without splitting keys or walking each path from the root unflatten() split every key into a vector of reference tokens, stored the pointer prefixes in a tree to decide which values become arrays, and then looked up every token of every key from the root again. Keys are now checked by a scan that raises the same parse_error.107/108 as split(), skipping the part a key shares with the previous one, which was checked already. The prefixes that denote arrays are kept in a small hash set of key slices; the array/object decision is unchanged. The walk keeps the values along the previous key's path, so only the part of a key that differs from the previous one is looked up. Keys of a flattened object are usually sorted, so that part is short. unflatten() of canada.json, citm_catalog.json and twitter.json is 1.9x to 2.3x as fast; the output and the exceptions are unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Apply plain JSON Patch operations without building a json_pointer patch() built a json_pointer for every operation, which splits the path into a vector of strings, and for "add" and "remove" a second one for the parent. That took 20% to 45% of the time not spent copying the document. "add", "remove", "replace" and "test" with a path that has no escapes and denotes existing values (the parent, for "add"), as diff() creates them, are now applied by resolving the path in place, reusing one string for the reference tokens. Every other operation, and every operation that would fail, takes the existing code, so the results, the exceptions and the state left after a failing operation are unchanged. patch() of the diffs of canada.json, citm_catalog.json and twitter.json is 1.02x to 1.10x as fast; the rest is the copy of the document. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Build diff operations member by member diff() created every operation from an initializer list, so each {"op", "replace"} pair became a temporary array with two heap strings before it was turned into an object member; an operation took about 25 allocations. The operations are now built as objects whose members are assigned one by one. Paths of members and elements are also built in place, without a temporary string for each escaped key or array index. diff() of canada.json, citm_catalog.json and twitter.json, with every eighth scalar changed, is 1.3x to 1.6x as fast; the output is unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Diff objects with the same keys in lockstep and keep one path buffer diff() looked up every key of the source object in the target object, and built a new string for the path of every value it descended into. Objects of the same size usually have the same keys in the same order, so they are now walked together as long as that holds, without a lookup; objects that differ fall back to the lookup from the first key that does not match. The path is one buffer that is extended before descending and shortened again afterwards. Objects whose members are equal but in a different order (possible with ordered_json) still get no operations. Together with the previous commit, diff() of canada.json, citm_catalog.json and twitter.json is 1.5x to 2.0x as fast; ordered_json 1.65x to 1.85x. The output is unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Use std::array for the index buffer in append_index() Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Declare the partner iterator in the loop initializer in diff_object_keys() Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix GCC and clang-tidy warnings in the JSON pointer speedups Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>