1083 Commits

Author SHA1 Message Date
Daniel Lemire dc485f845d let us use lower-case words for layout_mode (#2740) 2026-05-29 17:43:33 -04:00
Daniel Lemire 57561f64f4 adding warning that this is experimental. 2026-05-26 15:19:32 -04:00
Makkar 5db72ab9d3 add: C++26 annotations support for rename and skip (#2730) 2026-05-26 12:58:46 -04:00
Daniel Lemire 7732480b25 we need to require rvv for the risc64 kernel 2026-05-18 17:24:56 -04:00
wankun 1ae93a70d4 Bug fix for get_string() crash when parse incomplete json string (in option disabled my default) (#2720)
* get_string() crash when parse incomplete json string

* get_string() crash when parse incomplete json string

* Bug fix for RISC-V fail

* Update tests/ondemand/CMakeLists.txt

Co-authored-by: Daniel Lemire <daniel@lemire.me>

* Remove unnecessary changes

---------

Co-authored-by: Daniel Lemire <daniel@lemire.me>
2026-05-18 17:18:58 -04:00
吴杨帆 396ca141fd perf(builder): add LSX fast_needs_escaping for LoongArch (#2727)
Use LSX intrinsics for the string-builder escape scan on LoongArch,
matching the existing find_next_json_quotable_character LSX path.

Fixes #2603
2026-05-18 17:13:43 -04:00
Daniel Lemire ec49efa5da avoid unnecessary pointer member (#2715) 2026-05-08 00:26:57 -04:00
Daniel Lemire a16e5128fe pendantic guard 2026-05-07 23:13:40 -04:00
Alecto Irene Perez bd42858383 fix -Wunneeded-internal-declaration warning (#2714) 2026-05-07 21:46:52 -04:00
jmestwa-coder 7d30ff2574 JSON Pointer array index overflow handling (#2713) 2026-05-07 19:07:39 -04:00
Francisco Geiman Thiesen 42c047a927 builder: position-as-local writer for reflection serializer (#2708)
The dominant cost in the reflection serializer was the strict-aliasing
reload pattern: every char* write through `string_builder::buffer.get()`
forced the compiler to assume `string_builder::position` and `::capacity`
may have been clobbered, so it reloaded both members from memory after
each byte. perf annotate showed `ldr [position]` and `ldr [capacity]`
taking 15-20% of CITM serialization time.

This change refactors the reflection atom path to use an internal
`writer` struct (buffer pointer + position + capacity + back-ref to
string_builder). The writer lives as a stack-local in the top-level
append() entry point, threaded through the inlined atom() chain via
`writer&`. After SROA, the three fields are register-resident across
the entire serialization. The `pos` is never round-tripped through
memory between writes — it's a local size_t.

This mirrors the pattern Glaze uses (passing `B&& b, auto&& ix` through
every helper). The simdjson-specific bit is keeping the public
string_builder API intact: only the internal atom() family is
refactored to take `writer&`. The top-level append(string_builder&, T)
constructs a writer on the stack, threads it through atom(), then
syncs the local position back at the end.

For string fields specifically, the escape path is also inlined
through the writer — the existing `write_string_escaped(input, out)`
helper already takes a destination pointer and returns bytes-written,
so it composes cleanly with `w.ptr + w.pos`. Without this, sync/
reload around each string write was a real cost on Twitter (-7%).

Performance
===========

TRUE A/B in single docker invocation, 7 alternating rounds, byte-
identical output, all static_reflection_comprehensive_tests pass.
Build: clang-p2996 21.0.0git, -O3 -DNDEBUG, aarch64 Linux.

CITM Catalog (496 682 bytes):
  baseline (master): 4356 MB/s
  patched:           6776 MB/s   +55.5%
  Glaze:             4860 MB/s   simdjson now 39.4% AHEAD of Glaze

Twitter (81 927 bytes):
  baseline (master): 6437 MB/s
  patched:           6452 MB/s   +0.2% (break-even)
  Twitter is string-heavy; the writer's gain over the existing
  member-based path is small here, but it no longer regresses.

Default initial capacity is unchanged at 1024.
2026-05-07 13:28:03 -04:00
Alecto Irene Perez 376ef7e8e9 Add support for writing NaN/Infinity if SIMDJSON_ENABLE_NAN_INF is enabled (#2711)
* Add tests for dumping out NaN/Infinity to the json builder

* If SIMDJSON_ENABLE_NAN_INF is set, write out NaN and Infinity

* Add tests for dumping out NaN/Infinity when serializing DOM

* If SIMDJSON_ENABLE_NAN_INF, use 'NaN' and 'Infinity' for nan/inf

* Fix bug where 'Inf' as a root atom + spaces of padding parses incorrectly

* Update FracturedJson printers so tables containing NaN/Infinity are aligned
2026-05-07 13:11:03 -04:00
Daniel Lemire 9803884546 overflow patch. 2026-05-06 17:37:18 -04:00
Alecto Irene Perez b9b20be80e Add support for parsing NaN and Infinity as requested in #1540, #2414, and #2540 (#2696)
* add compile option 'SIMDJSON_ENABLE_NAN_INF' but disable by default

* extend parser to support NaN/Infinity when SIMDJSON_ENABLE_NAN_INF=1

* update tests to check parsing of NaN/Infinity, when enabled

* update minefield tests: mark nan/inf tests as passing when nan/inf is ON

* update CI/CD to run tests with extensions for NaN/Infinity enabled
2026-05-04 15:24:26 -04:00
Francisco Geiman Thiesen f902769b35 builder: force-inline atom templates and replace integer writer (#2707)
* builder: force-inline atom templates and replace integer writer

Two complementary changes that together speed up reflection-driven JSON
serialization by ~28% on integer-heavy structs (CITM) and ~12% on
string-heavy structs (Twitter).

(1) Add simdjson_really_inline (always_inline) to the hot atom<T>
    template overloads (arithmetic, struct, container, optional,
    string-like). The constexpr-only declaration was only a hint; the
    compiler routinely chose to leave atom<unsigned long> as a real
    out-of-line function.

(2) Replace string_builder::append<UInt> body with a forward
    cascade-on-magnitude integer writer. The old code computed
    digit_count(v) upfront and wrote backward in a loop; the new code is
    a straight-line if/else cascade that writes digits forward, no loop,
    no helper call.

Either change alone gives only modest gains. Together they unlock the
compiler's cross-call optimization: with all atoms inlined and the
integer writer reduced to straight-line code, the compiler can hoist
b.position into a register across the whole struct serialization, fold
redundant capacity_check calls, and eliminate the strict-aliasing
penalty that otherwise forces b.position/b.capacity reloads after every
char* write.

Output is byte-identical to master on CITM (496682 bytes) and Twitter
(81927 bytes). All static_reflection_comprehensive_tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* builder: de-recurse write_uint_jeaiii so always_inline applies on g++/MSVC

g++ ('inlining failed in call to always_inline ...: function not
considered for inlining') and MSVC ('warning C4714: __forceinline not
inlined' under warnings-as-errors) both refuse to inline recursive
functions marked simdjson_really_inline. The original write_uint_jeaiii
called itself in the >=10^4 branches.

Refactor into a non-recursive DAG of helpers: write_lt100, write_lt10000,
write_4_digits, write_lt1e8, write_uint_jeaiii. Each calls strictly
smaller-domain helpers, no cycles. Same straight-line cascade behavior,
same byte output, but every node is now a candidate for always_inline on
all compilers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* builder: port signed-int append to jeaiii writer and drop digit_count helpers

The signed-integer branch in string_builder::append was structurally
identical to the OLD unsigned branch — same digit_count() upfront +
backward 4-digit batched loop. Port it to use the same forward
write_uint_jeaiii() helper as the unsigned branch (write '-'
unconditionally and advance position only if negative — branchless).

This makes int_log2 / fast_digit_count_32 / fast_digit_count_64 /
digit_count fully unused (verified via grep across include/ and src/);
remove them, ~80 lines of dead code.

The signed write path now benefits from the same compiler-level
optimization (full inlining, capacity-check fusion, no opaque-loop
boundary) as the unsigned path. Signed-int microbench (200 × 100k
values, mixed magnitude and sign): 2272 → 2685 MB/s (+18.2%).
CITM and Twitter benchmarks unchanged in shape and remain byte-identical
to baseline output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix tests

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Daniel Lemire <daniel@lemire.me>
2026-05-04 13:55:49 -04:00
Daniel Lemire 389f7ce8e3 fixing issue 2703 (#2705) 2026-04-30 21:59:36 -04:00
Francisco Geiman Thiesen 32b52e3f34 builder: coalesce per-field separator+key+colon into one constexpr write (#2698)
Each non-first field in a reflection-driven struct serialization was
emitting three separate string_builder::append calls (',', "\"key\"", ':'),
each going through capacity_check + a small write. Combine them into a
single compile-time string per field so each field does one capacity_check
and one memcpy. Same pattern fixed in atom(), append(), and extract_from().

Measured under clang-p2996 -O3 -DNDEBUG -freflection -std=c++26
(median of 5 contemporaneous runs, output byte-identical to baseline):

  CITM serialization (496682 bytes):
    simdjson_reuse_buffer:        3192 -> 3673 MB/s  (+15.1%)
    simdjson_static_reflection:   3014 -> 3443 MB/s  (+14.2%)
    simdjson_to:                  2717 -> 3234 MB/s  (+19.0%)
    simdjson_to_reuse:            2836 -> 3226 MB/s  (+13.7%)

  Twitter serialization (81927 bytes):
    simdjson_reuse_buffer:        6637 -> 7162 MB/s   (+7.9%)
    simdjson_static_reflection:   5527 -> 5915 MB/s   (+7.0%)
    simdjson_to:                  5070 -> 5350 MB/s   (+5.5%)
    simdjson_to_reuse:            4976 -> 5303 MB/s   (+6.6%)

  extract_from (out-of-tree micro-bench, 100 records per call):
    User 4-of-9 fields:           1833 -> 1888 MB/s   (+3.0%)
    Status 3-of-6 fields:         4286 -> 4334 MB/s   (+1.1%)

Parsing benchmarks unchanged. tests/builder/static_reflection_comprehensive_tests
still passes (round-trip through extract_from / extract_into is verified).
2026-04-30 21:02:41 -04:00
jmestwa-coder b3fe96cdb2 Align source() output for comma-delimited streams with json_sequence behavior (#2699) 2026-04-29 13:05:45 -04:00
Daniel Lemire 63b10bca21 new optimization to the ARM NEON kernel (#2692)
* new optimization to the ARM NEON kernel

* portability hack
2026-04-20 17:16:50 -04:00
Daniel Lemire 3b782fab7a fixes 2690 (typo) 2026-04-20 12:09:39 -04:00
Daniel Lemire df16e96767 fix: ondemand for wildcard matches (#2686)
* fixing issue 2684

* simplifying.

* update

* more fixes

* moving example

* adding forward declaration
2026-04-17 14:20:57 -04:00
Daniel Lemire 2e7ad956eb Merge branch 'master' of github.com:simdjson/simdjson 2026-04-15 12:52:47 -04:00
Daniel Lemire 30d7204312 pedantic guard 2026-04-15 12:52:31 -04:00
metsw24-max b6af1a0456 Fix undefined behavior in document_stream parsing due to unsafe std::isspace usage (#2680) 2026-04-14 23:03:44 -04:00
Daniel Lemire 7cc60672e3 Merge branch 'master' of github.com:simdjson/simdjson 2026-04-13 17:55:05 -04:00
Daniel Lemire 3ecda9ee99 pedantic checks for 32-bit systems who try to allocate enormous
capacities.
2026-04-13 17:54:35 -04:00
Daniel Lemire b648a5fc0a Add std::ranges support for On-Demand API (variant) (#2678)
* add std::ranges support for On-Demand API (#2382)

Add zero-cost range wrappers (array_range, object_range) that satisfy
std::ranges::input_range, enabling std::views::transform and other
C++20 range adaptors with the On-Demand parser.

Uses direct forwarding via simdjson_inline with no value buffering,
avoiding the per-element overhead (~20%) of the previous approach.
Guarded by SIMDJSON_SUPPORTS_RANGES.

* fix: replace non-ASCII em dash in test comment

The just_ascii CI check flags any non-ASCII characters in source files.

* let us see what we get with this...

* minor tweak

* minor update

* update doc

---------

Co-authored-by: Justin Li <justin53@bu.edu>
2026-04-13 15:25:02 -04:00
Daniel Lemire 4ec44e88c9 adding memory-file mapping to Windows + better doc (#2676)
* adding memory-file mapping to Windows.

* making memory-file mapping optional under windows, as it is fragile

* removing non-ascii

* saving.

* bumping up

* take 2
2026-04-12 18:12:31 -04:00
Daniel Lemire 8ea4c1c2e6 being more precise 2026-04-12 17:06:27 -04:00
Daniel Lemire 94c429aa70 finishing up the new streaming (#2674)
* finishing up the new streaming

* fixed silly warnings.

* tweak

* adding more tests

* minor fixes

* more fixes
2026-04-11 14:16:43 -04:00
Jaël Champagne Gareau 72e51a9a81 Add support for RFC 7464 JSON text sequences and comma-delimited documents (#2664)
* add support for RFC 7464 documents

* add threaded comma-delimited parse_many support

* fix failing tests in CI
2026-04-10 20:26:00 -04:00
Daniel Lemire 1a57afec1f Various guards (#2673)
* adding a guard in document::allocate.

Co-authored-by: jmestwa-coder jmestwa@gmail.com

* adding a max depth

Co-authored-by: jmestwa-coder jmestwa@gmail.com
2026-04-10 20:19:46 -04:00
Daniel Lemire 85cadf4074 adding a C++17 padded_input for convenience. (#2667)
* adding a C++17 padded_input for convenience.

* adding header

* tuning.

* being explicit

* reworking the docu

* avoid windows.h

* Update include/simdjson/padded_string_view-inl.h

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/ondemand/ondemand_padded_input.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/ondemand/ondemand_readme_examples.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update doc/performance.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* minor update

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-09 14:07:44 -04:00
Daniel Lemire bc48e72070 literals should be guarded (#2669) 2026-04-09 14:07:29 -04:00
Daniel Lemire 73e69a5e84 Get reflection working without warnings under GCC 16 (#2658)
* wip gcc16

* progress

* minor gcc16 fixes

* final step

* Update include/simdjson/padded_string-inl.h

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update include/simdjson/padded_string.h

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* renaming test function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-03 15:32:42 -04:00
Daniel Lemire fb83b114ef 4.6.1 2026-04-03 15:26:12 -04:00
jmestwa-coder 542cd7af71 parser.load(string_view) does not respect view length when opening files (#2659) 2026-04-03 15:25:03 -04:00
Daniel Lemire 769364abb2 simplifying the logic 2026-03-30 20:01:35 -04:00
Daniel Lemire f25d5f9fc2 4.6.0 (#2655) 2026-03-30 19:51:00 -04:00
Eyüp Can Akman 12fb30ae9c add get_int32() and get_uint32() to the On Demand API (#2638)
* add get_int32() and get_uint32() to the On Demand API

Add convenience methods that call get_int64()/get_uint64() and
range-check the result, returning NUMBER_OUT_OF_RANGE on overflow.

Added to value, document, document_reference, and their
simdjson_result wrappers.

Closes #1890

* fix document_reference streaming for get_int32/get_uint32

The document_reference getters delegated to document::get_int32/get_uint32
which call get_root_int64/get_root_uint64 with allow_trailing_content=true,
rejecting the next document in a stream as trailing content.

Call get_root_value_iterator().get_root_int64/get_root_uint64(false) directly
to allow trailing content, matching get_int64/get_uint64.

Add streaming tests for both getters.

* add get_int32/get_uint32 to basics.md

* add get_int32/get_uint32 to wrong-type error tests

* add get<uint32_t>/get<int32_t> template specializations

Wire the 32-bit getters into the generic get<T>() and get(T&)
dispatch so that doc.get<uint32_t>() compiles on C++11/14/17
without requiring the C++20 concepts path in std_deserialize.h.
2026-03-30 10:16:31 -04:00
uwezkhan 307ddd4415 Avoid overflow in padded_string_builder::reserve (#2654)
Co-authored-by: uwezkhan06 <uwezkhan055@gmail.com>
2026-03-30 10:13:08 -04:00
jmestwa-coder afb1c9f4b1 correct inverted clamp in set_max_capacity (#2651) 2026-03-29 15:54:28 -04:00
uwezkhan 9973f7b3a3 Fix fopen usage with string_view (#2652)
Co-authored-by: uwezkhan06 <uwezkhan055@gmail.com>
2026-03-29 15:54:11 -04:00
Daniel Lemire 18d612df15 4.5.0 2026-03-25 17:26:13 -04:00
harshanagd bddb23177e feat: Add DOM tape support for big integers (opt-in) (#2640)
When parser.number_as_string(true) is set and a number exceeds uint64
range, write the raw digits to the string buffer and emit a BIGINT ('Z')
tape tag instead of returning BIGINT_ERROR. Default behavior unchanged.

Changes:
- tape_type.h: add BIGINT = 'Z'
- dom_parser_implementation.h: add _number_as_string flag
- parser.h: add number_as_string() getter/setter
- parser-inl.h: propagate flag before parse
- tape_builder.h: visit_number checks flag on BIGINT_ERROR
- tape_writer.h: add append_bigint helper
- serialization-inl.h: handle BIGINT in serialization (raw digits)
- tape.md: document big integer tape format

Builds on PR #2139 which added BIGINT_ERROR detection.
All 119 existing tests pass — default behavior unchanged.

Closes #167

Co-authored-by: harshagd <harshagd@amazon.com>
2026-03-25 17:25:37 -04:00
Daniel Lemire b4a0fd3ff4 4.4.2 2026-03-20 11:12:35 -04:00
Levi Zim a1ff05a5e8 Fix RISC-V compilation without RVV (#2637)
#2617 introduced an RVV check that only checks if the compiler supports RVV intrinsics without checking if RVV is enabled at compile time.

This has caused compilation failure of node.js on riscv64. Fix it by appending a check for __riscv_vector.
2026-03-20 11:11:38 -04:00
Daniel Lemire 5395aacb8b v4.4.1 2026-03-17 12:39:07 -04:00
Daniel Lemire 781ea4b495 fixing issue https://github.com/nodejs/node/pull/62257 (#2631) 2026-03-17 12:38:11 -04:00
Jaël Champagne Gareau 03e8d14eee fix failing CI and rename misleading workflow name (#2630) 2026-03-15 18:40:08 -04:00