Files
json/docs/mkdocs/docs/api/basic_json_view/count.md
T
Niels Lohmann 8daec2b596 Scan json_view strings with SIMD and index large objects
Speed up json_view's parser with SIMD scanning and a hash table
for large objects.

Long runs of string bytes are scanned 16 bytes at a time with NEON
(AArch64, GCC and Clang) and SSE2 (x86-64), both baseline
instruction sets. Keys keep 16 table checks before the vector
loop, because their lengths repeat from record to record; string
values get 8, because their lengths vary more. Non-ASCII text is
validated 16 bytes at a time with simdjson's "lookup4" check
(Keiser and Lemire, 2021), with NEON on AArch64 and, on x86-64,
with SSSE3. SSSE3 is not part of baseline x86-64, so the check is
compiled for SSSE3 with a function attribute and used only where
CPUID reports it, which all x86-64 CPUs since about 2011 do; the
answer is cached in a statically initialized atomic, so there is
no guard of a local static and no global constructor. The same
input is accepted either way. JSON_VIEW_NO_SIMD selects the
portable code.

On x86-64, string runs are now checked vector-first: one SSE2
compare from the first byte finds the end of most keys and short
values, instead of a branch per byte for the first 8-16 bytes.
AArch64 keeps the byte-wise steps, where a NEON mask costs more and
the branches predict well. Entering an object or array no longer
stalls: open() stores the parent's frame field by field instead of
building it on the stack and reading it back with wider loads,
which waited for the narrower stores to retire.

Objects with 128 members or more get an open-addressing hash table
built when the object closes, so operator[], at(), find(),
contains(), count(), value(), and JSON pointers take constant time
on average in such objects; of duplicate keys, the first is kept,
as for the linear search. The idea comes from Boost.JSON.

simdjson is credited in simd.hpp's SPDX block, the README, and
license.md.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:42:32 +02:00

2.2 KiB

nlohmann::basic_json_view::count

size_type count(string_view_t key) const;
size_type count(const char* key) const;
size_type count(const string_t& key) const;

Returns #!cpp 1 if the value is an object with a member with key key, #!cpp 0 otherwise.

Parameters

key (in)
key value of the element to count

Return value

#!cpp 1 if the value is an object and has a member with key key, #!cpp 0 otherwise.

Exception safety

No-throw guarantee: this function never throws exceptions.

Complexity

Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length -- already known from the index, without reading the key bytes -- before comparing its content. Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time on average.

Notes

This method always returns #!cpp 0 when the value is not an object -- including a discarded view.

Unlike BasicJsonType::count(), whose return value can in principle exceed #!cpp 1 for an ObjectType that allows multiple entries per key, count() here never does: it is exactly contains() as #!cpp 0/#!cpp 1. This holds even if the source text has a duplicate key -- see the Notes on duplicate keys of operator[] -- because a #!cpp count() > 1 result would require counting every member with a matching key, not just finding the first one.

Examples

??? example

The example below validates that every transaction of a batch carries a mandatory `amount` field, using
`count()` before deciding whether to materialize a transaction at all.

```cpp
--8<-- "examples/basic_json_view__count.cpp"
```

Output:

```json
--8<-- "examples/basic_json_view__count.output"
```

See also

Version history

  • Added in version 3.13.0.