GH-50567: [C++] Introduce JsonWriter and migrate integration JSON writer#50568
GH-50567: [C++] Introduce JsonWriter and migrate integration JSON writer#50568Reranko05 wants to merge 7 commits into
Conversation
|
|
fd69d50 to
bb7fd90
Compare
|
@kou could you review this PR when you have a chance? |
kou
left a comment
There was a problem hiding this comment.
Could you check performance difference?
|
@kou, I compared the serialization performance of main: 2157.4 ms I didn't observe any measurable performance regression. |
|
@kou I investigated the failing workflows and they appear to be unrelated to this PR. Could you please verify? |
bb7fd90 to
c983eb0
Compare
There was a problem hiding this comment.
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).
|
Another thought - do we have conbench cpp micro benchmarks to monitor improvement of json parsing and writing? |
There was a problem hiding this comment.
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 |
| ArrayWriter(const std::string& name, const Array& array, JsonWriter* writer) | ||
| : name_(name), array_(array), writer_(writer) {} |
I wasn't able to find any existing Conbench C++ microbenchmarks covering JSON parsing or writing. I did run a local benchmark comparing |
cfe491e to
a25a245
Compare
|
@kou It was just a temporary benchmark. I used the following to measure I ran it 10 times on both |
@rok Does this approach work for you as well? |
Yes, this sounds good! |
Thanks. I also tried it. simdjson: 69 ms Is RapidJSON fast enough? Is simdjson not fast? Can we try naive namespace arrow::json {
class ARROW_EXPORT JsonWriter {
// ...
private:
// ...
std::ostringstream output_;
// ...
};
}
namespace arrow::json {
void JsonWriter::StartObject() {
MaybeComma();
output_ << "{";
needs_comma_ = false;
}
// ...If this performance is similar to simdjson/RapidJSON, they may not be so fast for writing. |
|
@kou I have a question regarding the benchmark results. Earlier, when I benchmarked |
|
I used I think that we need to use a release build to measure. I expect that simdjson uses SIMD for writing. It'll require a release build. |
|
@kou I reran the benchmark in a Release build using the same temporary benchmark ( Results:
So, in this benchmark, the
|
d791d88 to
ff3b25e
Compare
ff3b25e to
c461c63
Compare
|
Marking this as ready for review. The remaining CI failures appear to be unrelated to this change (dependency download, environment, or infrastructure issues). |

What changes are included?
This PR introduces a reusable
JsonWriterwrapper around simdjson's JSON builder API and migrates the integration JSON writer to use it instead of RapidJSON.Specifically, this PR:
JsonWriterabstraction inarrow/json.JsonWriter.JsonWriter.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-rowRecordBatch. The benchmark was run 10 times on bothmainand this branch.mainNo measurable performance regression was observed.
Are these changes tested?
Yes.
I added unit tests for
JsonWriterand verified that both JSON and integration tests pass locally:arrow-json-testarrow-json-integration-testAre there any user-facing changes?
No.