mirror of
https://github.com/nlohmann/json.git
synced 2026-10-06 14:40:32 +00:00
Scan strings vector-first on x86-64 and avoid a stall when nesting
- With SSE2, string runs are checked 16 bytes at a time from their first byte: one compare finds the end of most keys and short values, faster on x86-64 than a branch per byte. AArch64 keeps the byte steps (there, a NEON mask costs more and the branches predict well; vector-first was 20% slower on Apple M1). - open() stores the parent's frame field by field. Built on the stack and copied, it was read back by loads wider than its stores, which waited for them (store forwarding fails): 18% of the time on citm_catalog.json. Parse on x86-64 (GCC 13 / Clang 18, us): twitter 352 -> 306 / 316 -> 288, citm_catalog 1000 -> 770 / 843 -> 692, canada 1941 -> 1687 / 1978 -> 1722. Unchanged on Apple M1. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -828,14 +828,19 @@ indent_done:
|
||||
const auto idx = static_cast<std::uint32_t>(emit(k, 0, 0, static_cast<std::size_t>(p - b), 0) - base);
|
||||
if (depth != 0)
|
||||
{
|
||||
const frame f = {cur_idx, cur_count, cur_is_object};
|
||||
if (NLOHMANN_VIEW_LIKELY(depth <= 64))
|
||||
{
|
||||
cold.shallow[depth - 1] = f;
|
||||
// field by field: a frame put together on the stack and
|
||||
// copied would be read back wider than it was written,
|
||||
// and that load waits until the stores are done
|
||||
frame& f = cold.shallow[depth - 1];
|
||||
f.idx = cur_idx;
|
||||
f.count = cur_count;
|
||||
f.is_object = cur_is_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
cold.deep.push_back(f);
|
||||
cold.deep.push_back(frame{cur_idx, cur_count, cur_is_object});
|
||||
}
|
||||
}
|
||||
++depth;
|
||||
@@ -851,19 +856,21 @@ indent_done:
|
||||
n.next = static_cast<std::uint32_t>(out - base) - cur_idx;
|
||||
if (--depth != 0)
|
||||
{
|
||||
frame f{};
|
||||
if (NLOHMANN_VIEW_LIKELY(depth <= 64))
|
||||
{
|
||||
f = cold.shallow[depth - 1];
|
||||
const frame& f = cold.shallow[depth - 1];
|
||||
cur_idx = f.idx;
|
||||
cur_count = f.count;
|
||||
cur_is_object = f.is_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = cold.deep.back();
|
||||
const frame f = cold.deep.back();
|
||||
cold.deep.pop_back();
|
||||
cur_idx = f.idx;
|
||||
cur_count = f.count;
|
||||
cur_is_object = f.is_object;
|
||||
}
|
||||
cur_idx = f.idx;
|
||||
cur_count = f.count;
|
||||
cur_is_object = f.is_object;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user