Skip to content

GH-50567: [C++] Introduce JsonWriter and migrate integration JSON writer#50568

Draft
Reranko05 wants to merge 3 commits into
apache:mainfrom
Reranko05:gh-35460-json-writer-v2
Draft

GH-50567: [C++] Introduce JsonWriter and migrate integration JSON writer#50568
Reranko05 wants to merge 3 commits into
apache:mainfrom
Reranko05:gh-35460-json-writer-v2

Conversation

@Reranko05

@Reranko05 Reranko05 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What changes are included?

This PR introduces a reusable JsonWriter wrapper around simdjson's JSON builder API and migrates the integration JSON writer to use it instead of RapidJSON.

Specifically, this PR:

  • Adds a reusable JsonWriter abstraction in arrow/json.
  • Migrates the integration JSON writer implementation to JsonWriter.
  • Updates the integration tests to use JsonWriter.
  • Adds unit tests for JsonWriter.

This is part of the incremental migration from RapidJSON to simdjson.

Performance

I compared the serialization performance of IntegrationJsonWriter::WriteRecordBatch() + Finish() using a temporary benchmark with a 1M-row RecordBatch. The benchmark was run 10 times on both main and this branch.

Branch Average Time
main 2157.4 ms
This PR 2153.6 ms

No measurable performance regression was observed.

Are these changes tested?

Yes.

I added unit tests for JsonWriter and verified that both JSON and integration tests pass locally:

  • arrow-json-test
  • arrow-json-integration-test

Are there any user-facing changes?

No.

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #50567 has been automatically assigned in GitHub to PR creator.

@Reranko05
Reranko05 force-pushed the gh-35460-json-writer-v2 branch 3 times, most recently from fd69d50 to bb7fd90 Compare July 21, 2026 06:02
@Reranko05

Copy link
Copy Markdown
Contributor Author

@kou could you review this PR when you have a chance?

@kou kou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you check performance difference?

Comment thread cpp/src/arrow/integration/json_internal.cc Outdated
@kou kou added the CI: Extra Run extra CI label Jul 21, 2026
@github-actions github-actions Bot added awaiting changes Awaiting changes and removed awaiting review Awaiting review labels Jul 21, 2026
@Reranko05

Copy link
Copy Markdown
Contributor Author

@kou, I compared the serialization performance of IntegrationJsonWriter::WriteRecordBatch() + Finish() using a temporary benchmark with a 1M-row RecordBatch. I ran the benchmark 10 times on both main and this branch. After excluding one obvious outlier from each run, the averages were:

main: 2157.4 ms
this branch: 2153.6 ms

I didn't observe any measurable performance regression.

@Reranko05

Copy link
Copy Markdown
Contributor Author

@kou I investigated the failing workflows and they appear to be unrelated to this PR. Could you please verify?

@Reranko05
Reranko05 force-pushed the gh-35460-json-writer-v2 branch from bb7fd90 to c983eb0 Compare July 21, 2026 12:41
@github-actions github-actions Bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Jul 21, 2026

@rok rok left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this @Reranko05! Exciting to see this work!

We should probably add meson support for json_writer, see (cpp/src/arrow/meson.build, cpp/src/arrow/json/meson.build, cpp/src/arrow/integration/meson.build).

Comment thread cpp/src/arrow/json/json_writer_internal.h
private:
void MaybeComma();

simdjson::builder::string_builder builder_;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently require simdjson 3.0.0, but builder API was introduced in simdjson 4.0.0. Are we sure this will build for 3.0.0 <= version < 4.0.0? Can you do a (local) test to show what's the minimum simdjson version we need for introduced features?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://repology.org/project/simdjson/versions - ubuntu seems to lag a bit.

@Reranko05 Reranko05 Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's a good point. Ubuntu is lagging so bumping up the minimum version will not work.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into reworking the implementation to remain compatible with 3.x.

@rok rok Jul 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure writing is possible pre-4.x so we likely want to raise the version. If we do so, how do we support ubuntu<25?
cc @lemire

@github-actions github-actions Bot added awaiting changes Awaiting changes and removed awaiting change review Awaiting change review labels Jul 21, 2026
@rok

rok commented Jul 21, 2026

Copy link
Copy Markdown
Member

Another thought - do we have conbench cpp micro benchmarks to monitor improvement of json parsing and writing?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a reusable arrow::json::JsonWriter wrapper around simdjson’s builder API and migrates the C++ integration JSON writer (and its tests) away from RapidJSON’s writer, as part of the incremental RapidJSON → simdjson migration.

Changes:

  • Added arrow::json::JsonWriter (header/impl) plus unit tests.
  • Migrated integration JSON serialization code paths to emit JSON using JsonWriter.
  • Updated CMake/test linkage and CI environment to ensure simdjson is available/linked where needed.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cpp/src/arrow/json/json_writer.h Introduces the JsonWriter public API.
cpp/src/arrow/json/json_writer.cc Implements JsonWriter on top of simdjson builder primitives.
cpp/src/arrow/json/json_writer_test.cc Adds unit coverage for basic writer operations.
cpp/src/arrow/json/CMakeLists.txt Adds the new unit test and links simdjson for the test target.
cpp/src/arrow/integration/json_internal.h Updates writer function signatures to accept arrow::json::JsonWriter*.
cpp/src/arrow/integration/json_internal.cc Migrates integration JSON emission to JsonWriter (writer-side).
cpp/src/arrow/integration/json_integration.cc Switches IntegrationJsonWriter implementation to JsonWriter.
cpp/src/arrow/integration/json_integration_test.cc Updates integration tests to use JsonWriter for schema/array JSON generation.
cpp/src/arrow/integration/CMakeLists.txt Links simdjson where integration tests/executables now depend on it.
cpp/src/arrow/CMakeLists.txt Adds json/json_writer.cc to Arrow JSON sources and links simdjson for integration targets.
ci/docker/ubuntu-24.04-cpp.dockerfile Sets simdjson_SOURCE=BUNDLED to ensure simdjson availability in CI images.


namespace arrow::internal::integration::json {

/// \brief Append integration test Schema format to rapidjson writer
Comment on lines +475 to 476
ArrayWriter(const std::string& name, const Array& array, JsonWriter* writer)
: name_(name), array_(array), writer_(writer) {}
Comment thread cpp/src/arrow/integration/json_internal.h Outdated
Comment thread cpp/src/arrow/json/json_writer_internal.h
Comment thread cpp/src/arrow/json/json_writer.h Outdated
@github-actions github-actions Bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Jul 21, 2026
@Reranko05

Copy link
Copy Markdown
Contributor Author

Another thought - do we have conbench cpp micro benchmarks to monitor improvement of json parsing and writing?

I wasn't able to find any existing Conbench C++ microbenchmarks covering JSON parsing or writing. I did run a local benchmark comparing IntegrationJsonWriter::WriteRecordBatch() + Finish() on this branch against main and didn't observe any measurable regression. If I missed an existing Conbench benchmark, please let me know and I will run this against it.

@Reranko05
Reranko05 force-pushed the gh-35460-json-writer-v2 branch from cfe491e to a25a245 Compare July 21, 2026 14:45
@Reranko05
Reranko05 force-pushed the gh-35460-json-writer-v2 branch from a25a245 to 106ee16 Compare July 21, 2026 14:50
@rok

rok commented Jul 21, 2026

Copy link
Copy Markdown
Member

If I missed an existing Conbench benchmark, please let me know and I will run this against it.

It then seems we currently don't benchmark serializing and deserializing json. It would be useful to introduce some, but perhaps that is out of scope for this ticket.

@rok

rok commented Jul 21, 2026

Copy link
Copy Markdown
Member

See this PR for an example how to implement a benchmark.

@pitrou

pitrou commented Jul 21, 2026

Copy link
Copy Markdown
Member

It then seems we currently don't benchmark serializing and deserializing json. It would be useful to introduce some, but perhaps that is out of scope for this ticket.

It doesn't sound useful to benchmark JSON parsing for integration testing.

@rok

rok commented Jul 21, 2026

Copy link
Copy Markdown
Member

It seems we do have some - search for json on http://conbench.arrow-dev.org/c-benchmarks/.
Here are examples: ReadJSONBlockWithSchemaSingleThread, ReadJSONBlockWithSchemaMultiThread. Source code.

@pitrou

pitrou commented Jul 21, 2026

Copy link
Copy Markdown
Member

They are testing the JSONL reader, not the JSON integration reader.

@rok

rok commented Jul 21, 2026

Copy link
Copy Markdown
Member

It doesn't sound useful to benchmark JSON parsing for integration testing.

yeah, that is not very interesting indeed.

@Reranko05 sorry for bringing up benchmarks here, we likely don't need new ones here.

@pitrou did we ever discuss JSONL writer?

@pitrou

pitrou commented Jul 21, 2026

Copy link
Copy Markdown
Member

@pitrou did we ever discuss JSONL writer?

There's probably an issue open for it :)

@rok

rok commented Jul 21, 2026

Copy link
Copy Markdown
Member

@pitrou did we ever discuss JSONL writer?

There's probably an issue open for it :)

There is an issue and a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting change review Awaiting change review CI: Extra Run extra CI Component: C++

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants