Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf9bc9f71b | ||
|
|
9e1d35eda9 | ||
|
|
4b538d80f6 | ||
|
|
91a8503f83 | ||
|
|
66ee5d1b84 | ||
|
|
7a4e6b7a5d | ||
|
|
a4c4e92dbd | ||
|
|
ae57b09bc6 | ||
|
|
fd37b04813 | ||
|
|
e89d5fdbdd | ||
|
|
d587214ab2 | ||
|
|
bd442d5d07 | ||
|
|
4c3e92b96e | ||
|
|
087df7b0c2 | ||
|
|
eae3c8217b | ||
|
|
960c234cc6 | ||
|
|
b6e24d19a9 |
No files matched your search
@@ -154,6 +154,15 @@ and each page's title (H1) and declaration by
|
||||
[`docs/docset/generate_docset.py`](https://github.com/nlohmann/json/blob/develop/docs/docset/generate_docset.py);
|
||||
`make build` reports API pages that cannot be classified.
|
||||
|
||||
A pull request that changes only the documentation, Markdown files, GitHub metadata, or license files skips the
|
||||
compiler workflows (Ubuntu, macOS, Windows); the documentation and license checks still run. See
|
||||
[`tools/check_path_filters`](https://github.com/nlohmann/json/tree/develop/tools/check_path_filters) for the list of
|
||||
skipped files and what to do when a compiler job starts reading one of them.
|
||||
|
||||
Most compiler jobs run only once a maintainer adds the label "🚀 ready to merge" to a pull request; until then, a
|
||||
smaller set of jobs runs on every push. See
|
||||
[How CI runs](https://json.nlohmann.me/community/quality_assurance/#how-ci-runs) for the sets and when they run.
|
||||
|
||||
### Amalgamate the source code
|
||||
|
||||
The single-header files
|
||||
|
||||
@@ -7,25 +7,60 @@ on:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
# labeled: the "🚀 ready to merge" label starts the full set (see below)
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
# Skip pull requests that change only files no job here reads. The list is checked by
|
||||
# tools/check_path_filters/check_path_filters.py (repository_checks.yml); change both together.
|
||||
paths:
|
||||
- '**'
|
||||
- '!docs/**'
|
||||
- '!**.md'
|
||||
- '!.github/*'
|
||||
- '!.github/ISSUE_TEMPLATE/**'
|
||||
- '!.github/external_ci/**'
|
||||
- '!.github/workflows/**'
|
||||
- '!.reuse/**'
|
||||
- '!LICENSES/**'
|
||||
- '!CITATION.cff'
|
||||
- '!REUSE.toml'
|
||||
# read by tools/check_build_options in the ci_meson_install job (ubuntu.yml)
|
||||
- 'docs/mkdocs/docs/integration/package_managers.md'
|
||||
# built by the swiftpm job (macos.yml)
|
||||
- 'docs/mkdocs/docs/integration/swift/**'
|
||||
- '.github/workflows/macos.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
# A run triggered by any other label gets a group of its own, so it does not
|
||||
# cancel the run of the last push; its jobs are skipped.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'schedule' && 'nightly' || github.ref || github.run_id }}${{ github.event.action == 'labeled' && github.event.label.name != '🚀 ready to merge' && format('-{0}', github.run_id) || '' }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
||||
# The jobs are split into a PR set and a full set like in ubuntu.yml (see "How
|
||||
# CI runs" in docs/mkdocs/docs/community/quality_assurance.md): the PR set runs
|
||||
# on every push; the full set after the PR set passed, on pushes and on pull
|
||||
# requests with the "🚀 ready to merge" label. tools/ci_jobs checks that every
|
||||
# job belongs to exactly one set.
|
||||
|
||||
jobs:
|
||||
###########################################################################
|
||||
# PR set
|
||||
###########################################################################
|
||||
|
||||
macos-15:
|
||||
if: &pr_set ${{ github.event_name != 'schedule' && (github.event.action != 'labeled' || github.event.label.name == '🚀 ready to merge') }}
|
||||
runs-on: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
|
||||
strategy:
|
||||
matrix:
|
||||
xcode: ['16.0', '16.1', '16.2', '16.3', '16.4', '26.0.1', '26.1.1', '26.2', '26.3']
|
||||
xcode: ['16.0', '16.4', '26.3']
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||
|
||||
steps:
|
||||
steps: &xcode_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -37,10 +72,11 @@ jobs:
|
||||
run: cd build ; ctest -j 10 --output-on-failure
|
||||
|
||||
macos-26:
|
||||
if: *pr_set
|
||||
runs-on: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
|
||||
strategy:
|
||||
matrix:
|
||||
xcode: ['26.4.1', '26.5', '26.6']
|
||||
xcode: ['26.6']
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||
|
||||
@@ -56,12 +92,13 @@ jobs:
|
||||
run: cd build ; ctest -j 10 --output-on-failure
|
||||
|
||||
xcode_standards:
|
||||
if: *pr_set
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [11, 14, 17, 20, 23, 26]
|
||||
standard: [14]
|
||||
|
||||
steps:
|
||||
steps: &xcode_standards_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -73,6 +110,7 @@ jobs:
|
||||
run: cd build ; ctest -j 10 --output-on-failure
|
||||
|
||||
swiftpm:
|
||||
if: *pr_set
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -106,3 +144,42 @@ jobs:
|
||||
EOF
|
||||
cd /tmp/json-swiftpm-consumer
|
||||
swift build
|
||||
|
||||
|
||||
###########################################################################
|
||||
# full set: starts after the PR set passed
|
||||
###########################################################################
|
||||
|
||||
macos-15_full:
|
||||
needs: &pr_set_jobs [macos-15, macos-26, xcode_standards, swiftpm]
|
||||
if: &full_set ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, '🚀 ready to merge') }}
|
||||
runs-on: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
|
||||
strategy:
|
||||
matrix:
|
||||
xcode: ['16.1', '16.2', '16.3', '26.0.1', '26.1.1', '26.2']
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||
|
||||
steps: *xcode_steps
|
||||
|
||||
macos-26_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
|
||||
strategy:
|
||||
matrix:
|
||||
xcode: ['26.4.1', '26.5']
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||
|
||||
steps: *xcode_steps
|
||||
|
||||
xcode_standards_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [11, 17, 20, 23, 26]
|
||||
|
||||
steps: *xcode_standards_steps
|
||||
@@ -0,0 +1,83 @@
|
||||
name: Repository checks
|
||||
|
||||
# Checks that concern files the compiler workflows (ubuntu.yml, macos.yml,
|
||||
# windows.yml) skip with their path filter: the documentation, the license
|
||||
# information, and the CI configuration itself. This workflow has no path filter.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check_ci_configuration:
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check the path filters of the compiler workflows
|
||||
run: python3 tools/check_path_filters/check_path_filters.py
|
||||
- name: Check the job sets of the compiler workflows and their documentation
|
||||
run: |
|
||||
python3 -m venv venv
|
||||
venv/bin/pip install --quiet -r tools/ci_jobs/requirements.txt
|
||||
venv/bin/python tools/ci_jobs/ci_jobs.py
|
||||
|
||||
ci_reuse_compliance:
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_reuse_compliance
|
||||
|
||||
ci_test_documentation:
|
||||
runs-on: ubuntu-26.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_examples, ci_test_build_documentation, ci_test_documentation_mermaid]
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
# the git-revision-date-localized plugin needs the history; a shallow clone makes the strict build fail
|
||||
fetch-depth: ${{ matrix.target == 'ci_test_build_documentation' && '0' || '1' }}
|
||||
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
||||
if: matrix.target == 'ci_test_documentation_mermaid'
|
||||
with:
|
||||
node-version: 24
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
@@ -7,17 +7,62 @@ on:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
# labeled: the "🚀 ready to merge" label starts the full set (see below)
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
# Skip pull requests that change only files no job here reads. The list is checked by
|
||||
# tools/check_path_filters/check_path_filters.py (repository_checks.yml); change both together.
|
||||
paths:
|
||||
- '**'
|
||||
- '!docs/**'
|
||||
- '!**.md'
|
||||
- '!.github/*'
|
||||
- '!.github/ISSUE_TEMPLATE/**'
|
||||
- '!.github/external_ci/**'
|
||||
- '!.github/workflows/**'
|
||||
- '!.reuse/**'
|
||||
- '!LICENSES/**'
|
||||
- '!CITATION.cff'
|
||||
- '!REUSE.toml'
|
||||
# read by tools/check_build_options in the ci_meson_install job (ubuntu.yml)
|
||||
- 'docs/mkdocs/docs/integration/package_managers.md'
|
||||
# built by the swiftpm job (macos.yml)
|
||||
- 'docs/mkdocs/docs/integration/swift/**'
|
||||
- '.github/workflows/ubuntu.yml'
|
||||
schedule:
|
||||
# the nightly set (see below), on develop
|
||||
- cron: '0 2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# A run triggered by any other label gets a group of its own, so it does not
|
||||
# cancel the run of the last push; its jobs are skipped.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'schedule' && 'nightly' || github.ref || github.run_id }}${{ github.event.action == 'labeled' && github.event.label.name != '🚀 ready to merge' && format('-{0}', github.run_id) || '' }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# The jobs are split into three sets (see "How CI runs" in
|
||||
# docs/mkdocs/docs/community/quality_assurance.md):
|
||||
#
|
||||
# - PR set: every pull request push and every push; chosen because these jobs
|
||||
# caught 92 % of the failing commits in Sep/Oct 2026.
|
||||
# - full set: after the PR set passed, on pushes and on pull requests with the
|
||||
# "🚀 ready to merge" label; every remaining compiler, version and standard.
|
||||
# - nightly set: slow tools and rare compilers, nightly on develop, on pushes
|
||||
# to master and release/*, and when started by hand.
|
||||
#
|
||||
# A matrix whose entries belong to different sets is split into one job per
|
||||
# set; the jobs share their steps through YAML anchors. tools/ci_jobs checks
|
||||
# that every job belongs to exactly one set.
|
||||
|
||||
jobs:
|
||||
###########################################################################
|
||||
# PR set
|
||||
###########################################################################
|
||||
|
||||
ci_test_gcc:
|
||||
if: &pr_set ${{ github.event_name != 'schedule' && (github.event.action != 'labeled' || github.event.label.name == '🚀 ready to merge') }}
|
||||
runs-on: ubuntu-latest
|
||||
container: gcc:latest
|
||||
steps:
|
||||
@@ -32,6 +77,7 @@ jobs:
|
||||
run: cmake --build build --target ci_test_gcc
|
||||
|
||||
ci_meson_install:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -76,7 +122,342 @@ jobs:
|
||||
cmake -S tests/cmake_import/project -B build-import-split -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-split
|
||||
cmake --build build-import-split
|
||||
|
||||
ci_static_analysis_ubuntu:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-26.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_cpplint]
|
||||
steps: &static_analysis_ubuntu_steps
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Install Valgrind
|
||||
if: matrix.target == 'ci_test_valgrind'
|
||||
run: sudo apt-get update ; sudo apt-get install -y valgrind
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
|
||||
ci_static_analysis_clang:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:22
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_single_binaries]
|
||||
steps: &static_analysis_clang_steps
|
||||
- name: Install git, clang-tools, iwyu (ci_single_binaries), and unzip
|
||||
run: apt-get update ; apt-get install -y git clang-tools iwyu unzip
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
|
||||
ci_cmake_options:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:24.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noglobaludls]
|
||||
steps: &cmake_options_steps
|
||||
- name: Install build-essential
|
||||
run: apt-get update ; apt-get install -y build-essential unzip wget git
|
||||
# the CMake 3.5.0 release binary that ci_cmake_flags downloads links
|
||||
# against libidn.so.11, which Ubuntu 24.04 no longer ships
|
||||
- name: Install libidn11 for CMake 3.5.0
|
||||
if: matrix.target == 'ci_cmake_flags'
|
||||
run: |
|
||||
wget -q http://archive.ubuntu.com/ubuntu/pool/main/libi/libidn/libidn11_1.33-2.2ubuntu2_amd64.deb
|
||||
dpkg -i libidn11_1.33-2.2ubuntu2_amd64.deb
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
|
||||
ci_test_compilers_gcc_old:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['4.8']
|
||||
# official gcc:4.8/4.9/5/6 images fail to check out code (too old for
|
||||
# actions/checkout); install the old compilers on top of official ubuntu:20.04
|
||||
# instead, mirroring what the (now retired) custom json-ci image did.
|
||||
container: ubuntu:20.04
|
||||
steps: &compilers_gcc_old_steps
|
||||
- name: Install g++-${{ matrix.compiler }}
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends software-properties-common ca-certificates gnupg make git
|
||||
# add-apt-repository resolves the PPA through the Launchpad API,
|
||||
# which intermittently times out or fails the team lookup (the plain
|
||||
# "deb ..." sources below never hit Launchpad and never flake).
|
||||
# Retry with backoff so a transient Launchpad blip does not fail CI.
|
||||
for attempt in 1 2 3 4 5; do
|
||||
add-apt-repository -y ppa:ubuntu-toolchain-r/test && break
|
||||
echo "::warning::add-apt-repository ppa:ubuntu-toolchain-r/test failed (attempt ${attempt}/5); retrying"
|
||||
sleep $((attempt * 10))
|
||||
done
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ bionic main"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ bionic universe"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial main"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial universe"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial-updates main"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial-updates universe"
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends g++-${{ matrix.compiler }}
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: CXX=g++-${{ matrix.compiler }} cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_g++-${{ matrix.compiler }}
|
||||
|
||||
ci_test_compilers_clang:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['3.4']
|
||||
container: silkeh/clang:${{ matrix.compiler }}
|
||||
steps: &compilers_clang_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Disable filesystem support (std::filesystem is unusable) for clang 7 / 8 / 9 / 10
|
||||
run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV"
|
||||
if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }}
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_default
|
||||
|
||||
ci_test_standards_gcc:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-latest
|
||||
container: gcc:latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [26]
|
||||
steps: &standards_gcc_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_gcc_cxx${{ matrix.standard }}
|
||||
|
||||
ci_test_standards_clang:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [26]
|
||||
stdlib: [libcxx]
|
||||
steps: &standards_clang_steps
|
||||
- name: Install git and unzip
|
||||
run: apt-get update ; apt-get install -y git unzip
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build with libc++
|
||||
run: cmake --build build --target ci_test_clang_libcxx_cxx${{ matrix.standard }}
|
||||
if: ${{ matrix.stdlib == 'libcxx' }}
|
||||
- name: Build with libstdc++
|
||||
run: cmake --build build --target ci_test_clang_cxx${{ matrix.standard }}
|
||||
if: ${{ matrix.stdlib == 'libstdcxx' }}
|
||||
|
||||
ci_emscripten:
|
||||
if: *pr_set
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Install emscripten
|
||||
uses: mymindstorm/setup-emsdk@4528d102f7230f0e7b276855c01ea1159be0e984 # v16
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -GNinja
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
###########################################################################
|
||||
# full set: starts after the PR set passed
|
||||
###########################################################################
|
||||
|
||||
ci_static_analysis_ubuntu_full:
|
||||
needs: &pr_set_jobs [ci_test_gcc, ci_meson_install, ci_static_analysis_ubuntu, ci_static_analysis_clang, ci_cmake_options, ci_test_compilers_gcc_old, ci_test_compilers_clang, ci_test_standards_gcc, ci_test_standards_clang, ci_emscripten]
|
||||
if: &full_set ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, '🚀 ready to merge') }}
|
||||
runs-on: ubuntu-26.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_single_header, ci_cppcheck, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata]
|
||||
steps: *static_analysis_ubuntu_steps
|
||||
|
||||
ci_static_analysis_clang_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:22
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_clang_analyze]
|
||||
steps: *static_analysis_clang_steps
|
||||
|
||||
ci_cmake_options_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:24.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_cmake_flags, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_delete_deprecated_functions, ci_test_no_thread_local]
|
||||
steps: *cmake_options_steps
|
||||
|
||||
ci_test_compilers_gcc_old_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['4.9', '5', '6']
|
||||
container: ubuntu:20.04
|
||||
steps: *compilers_gcc_old_steps
|
||||
|
||||
ci_test_compilers_gcc_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
# older GCC docker images (4, 5, 6) fail to check out code
|
||||
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', '16', 'latest']
|
||||
container: gcc:${{ matrix.compiler }}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_default
|
||||
|
||||
ci_test_compilers_clang_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['3.5', '3.6', '3.7', '3.8', '3.9', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15-bullseye', '16', '17', '18', '19', '20', '21', '22', 'latest']
|
||||
container: silkeh/clang:${{ matrix.compiler }}
|
||||
steps: *compilers_clang_steps
|
||||
|
||||
ci_test_standards_gcc_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
container: gcc:latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [11, 14, 17, 20, 23]
|
||||
steps: *standards_gcc_steps
|
||||
|
||||
ci_test_standards_clang_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [11, 14, 17, 20, 23, 26]
|
||||
stdlib: [libcxx, libstdcxx]
|
||||
exclude:
|
||||
# in the PR set
|
||||
- standard: 26
|
||||
stdlib: libcxx
|
||||
steps: *standards_clang_steps
|
||||
|
||||
ci_module_cpp20:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
strategy:
|
||||
matrix:
|
||||
container: ['gcc:latest', 'silkeh/clang:latest']
|
||||
runs-on: ubuntu-latest
|
||||
container: ${{ matrix.container }}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
# The module test uses `import std;`, which needs CMake's experimental
|
||||
# import-std support. Its opt-in token is CMake-version-specific, so pin
|
||||
# CMake to the version whose token is set in tests/module_cpp20/CMakeLists.txt.
|
||||
- name: Get pinned CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
with:
|
||||
cmakeVersion: 4.3.4
|
||||
# Clang: the std library module is provided by libc++ (the image's libstdc++
|
||||
# ships none), and the image's libc++ module manifest has a broken relative
|
||||
# path — repoint it at the real module sources.
|
||||
- name: Use libc++ and fix its module manifest path (Clang)
|
||||
if: matrix.container == 'silkeh/clang:latest'
|
||||
run: |
|
||||
echo "CXXFLAGS=-stdlib=libc++" >> "$GITHUB_ENV"
|
||||
mkdir -p /usr/lib/share && ln -sf /usr/lib/llvm-*/share/libc++ /usr/lib/share/libc++
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_module_cpp20
|
||||
|
||||
###########################################################################
|
||||
# nightly set
|
||||
###########################################################################
|
||||
|
||||
ci_infer:
|
||||
if: &nightly_set ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref != 'refs/heads/develop') }}
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
@@ -105,76 +486,16 @@ jobs:
|
||||
path: ${{ github.workspace }}/build/build_infer/infer-out/report.txt
|
||||
if-no-files-found: ignore
|
||||
|
||||
ci_static_analysis_ubuntu:
|
||||
ci_static_analysis_ubuntu_nightly:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-26.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind]
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Install Valgrind
|
||||
if: matrix.target == 'ci_test_valgrind'
|
||||
run: sudo apt-get update ; sudo apt-get install -y valgrind
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
|
||||
ci_static_analysis_clang:
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:22
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_clang_analyze, ci_single_binaries]
|
||||
steps:
|
||||
- name: Install git, clang-tools, iwyu (ci_single_binaries), and unzip
|
||||
run: apt-get update ; apt-get install -y git clang-tools iwyu unzip
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
|
||||
ci_cmake_options:
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:24.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_delete_deprecated_functions, ci_test_no_thread_local]
|
||||
steps:
|
||||
- name: Install build-essential
|
||||
run: apt-get update ; apt-get install -y build-essential unzip wget git
|
||||
# the CMake 3.5.0 release binary that ci_cmake_flags downloads links
|
||||
# against libidn.so.11, which Ubuntu 24.04 no longer ships
|
||||
- name: Install libidn11 for CMake 3.5.0
|
||||
if: matrix.target == 'ci_cmake_flags'
|
||||
run: |
|
||||
wget -q http://archive.ubuntu.com/ubuntu/pool/main/libi/libidn/libidn11_1.33-2.2ubuntu2_amd64.deb
|
||||
dpkg -i libidn11_1.33-2.2ubuntu2_amd64.deb
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
target: [ci_test_valgrind]
|
||||
steps: *static_analysis_ubuntu_steps
|
||||
|
||||
ci_test_coverage:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
@@ -208,128 +529,8 @@ jobs:
|
||||
path-to-lcov: ${{ github.workspace }}/build/json.info.filtered.noexcept
|
||||
fail-on-error: false
|
||||
|
||||
ci_test_compilers_gcc_old:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['4.8', '4.9', '5', '6']
|
||||
# official gcc:4.8/4.9/5/6 images fail to check out code (too old for
|
||||
# actions/checkout); install the old compilers on top of official ubuntu:20.04
|
||||
# instead, mirroring what the (now retired) custom json-ci image did.
|
||||
container: ubuntu:20.04
|
||||
steps:
|
||||
- name: Install g++-${{ matrix.compiler }}
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends software-properties-common ca-certificates gnupg make git
|
||||
# add-apt-repository resolves the PPA through the Launchpad API,
|
||||
# which intermittently times out or fails the team lookup (the plain
|
||||
# "deb ..." sources below never hit Launchpad and never flake).
|
||||
# Retry with backoff so a transient Launchpad blip does not fail CI.
|
||||
for attempt in 1 2 3 4 5; do
|
||||
add-apt-repository -y ppa:ubuntu-toolchain-r/test && break
|
||||
echo "::warning::add-apt-repository ppa:ubuntu-toolchain-r/test failed (attempt ${attempt}/5); retrying"
|
||||
sleep $((attempt * 10))
|
||||
done
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ bionic main"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ bionic universe"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial main"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial universe"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial-updates main"
|
||||
apt-add-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial-updates universe"
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends g++-${{ matrix.compiler }}
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: CXX=g++-${{ matrix.compiler }} cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_g++-${{ matrix.compiler }}
|
||||
|
||||
ci_test_compilers_gcc:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
# older GCC docker images (4, 5, 6) fail to check out code
|
||||
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', '16', 'latest']
|
||||
container: gcc:${{ matrix.compiler }}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_default
|
||||
|
||||
ci_test_compilers_clang:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['3.4', '3.5', '3.6', '3.7', '3.8', '3.9', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15-bullseye', '16', '17', '18', '19', '20', '21', '22', 'latest']
|
||||
container: silkeh/clang:${{ matrix.compiler }}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Disable filesystem support (std::filesystem is unusable) for clang 7 / 8 / 9 / 10
|
||||
run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV"
|
||||
if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }}
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_default
|
||||
|
||||
ci_test_standards_gcc:
|
||||
runs-on: ubuntu-latest
|
||||
container: gcc:latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [11, 14, 17, 20, 23, 26]
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_gcc_cxx${{ matrix.standard }}
|
||||
|
||||
ci_test_standards_clang:
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:latest
|
||||
strategy:
|
||||
matrix:
|
||||
standard: [11, 14, 17, 20, 23, 26]
|
||||
stdlib: [libcxx, libstdcxx]
|
||||
steps:
|
||||
- name: Install git and unzip
|
||||
run: apt-get update ; apt-get install -y git unzip
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build with libc++
|
||||
run: cmake --build build --target ci_test_clang_libcxx_cxx${{ matrix.standard }}
|
||||
if: ${{ matrix.stdlib == 'libcxx' }}
|
||||
- name: Build with libstdc++
|
||||
run: cmake --build build --target ci_test_clang_cxx${{ matrix.standard }}
|
||||
if: ${{ matrix.stdlib == 'libstdcxx' }}
|
||||
|
||||
ci_cuda_example:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -352,37 +553,8 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_cuda_example
|
||||
|
||||
ci_module_cpp20:
|
||||
strategy:
|
||||
matrix:
|
||||
container: ['gcc:latest', 'silkeh/clang:latest']
|
||||
runs-on: ubuntu-latest
|
||||
container: ${{ matrix.container }}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
# The module test uses `import std;`, which needs CMake's experimental
|
||||
# import-std support. Its opt-in token is CMake-version-specific, so pin
|
||||
# CMake to the version whose token is set in tests/module_cpp20/CMakeLists.txt.
|
||||
- name: Get pinned CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
with:
|
||||
cmakeVersion: 4.3.4
|
||||
# Clang: the std library module is provided by libc++ (the image's libstdc++
|
||||
# ships none), and the image's libc++ module manifest has a broken relative
|
||||
# path — repoint it at the real module sources.
|
||||
- name: Use libc++ and fix its module manifest path (Clang)
|
||||
if: matrix.container == 'silkeh/clang:latest'
|
||||
run: |
|
||||
echo "CXXFLAGS=-stdlib=libc++" >> "$GITHUB_ENV"
|
||||
mkdir -p /usr/lib/share && ln -sf /usr/lib/llvm-*/share/libc++ /usr/lib/share/libc++
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_module_cpp20
|
||||
|
||||
ci_icpc:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-latest
|
||||
# Intel discontinued the classic icc/icpc compiler in oneAPI 2024.0; this is
|
||||
# Intel's own last officially published image that still includes it.
|
||||
@@ -402,6 +574,7 @@ jobs:
|
||||
run: cmake --build build --target ci_icpc
|
||||
|
||||
ci_icpx:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-latest
|
||||
container: intel/oneapi-hpckit:latest
|
||||
steps:
|
||||
@@ -416,6 +589,7 @@ jobs:
|
||||
run: cmake --build build --target ci_icpx
|
||||
|
||||
ci_nvhpc:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-latest
|
||||
container: nvcr.io/nvidia/nvhpc:25.5-devel-cuda12.9-ubuntu22.04
|
||||
steps:
|
||||
@@ -429,54 +603,10 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_nvhpc
|
||||
|
||||
ci_emscripten:
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Install emscripten
|
||||
uses: mymindstorm/setup-emsdk@4528d102f7230f0e7b276855c01ea1159be0e984 # v16
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -GNinja
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
ci_test_documentation:
|
||||
runs-on: ubuntu-26.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [ci_test_examples, ci_test_build_documentation, ci_test_documentation_mermaid]
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
# the git-revision-date-localized plugin needs the history; a shallow clone makes the strict build fail
|
||||
fetch-depth: ${{ matrix.target == 'ci_test_build_documentation' && '0' || '1' }}
|
||||
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
||||
if: matrix.target == 'ci_test_documentation_mermaid'
|
||||
with:
|
||||
node-version: 24
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ${{ matrix.target }}
|
||||
|
||||
# Native Linux ARM64 runner with the latest GCC. The ubuntu-24.04-arm label is
|
||||
# only available for public repositories.
|
||||
ci_test_arm64:
|
||||
if: *nightly_set
|
||||
runs-on: ubuntu-24.04-arm
|
||||
container: gcc:latest
|
||||
steps:
|
||||
@@ -491,3 +621,33 @@ jobs:
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_test_compiler_default
|
||||
|
||||
# A failure of a scheduled run opens an issue, or comments on the open one.
|
||||
nightly_report:
|
||||
needs: [ci_infer, ci_static_analysis_ubuntu_nightly, ci_test_coverage, ci_cuda_example, ci_icpc, ci_icpx, ci_nvhpc, ci_test_arm64]
|
||||
if: ${{ always() && github.event_name == 'schedule' && contains(needs.*.result, 'failure') }}
|
||||
runs-on: ubuntu-26.04
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Open or update the nightly failure issue
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
WORKFLOW: ${{ github.workflow }}
|
||||
SHA: ${{ github.sha }}
|
||||
run: |
|
||||
title="Nightly CI failure (${WORKFLOW})"
|
||||
body="The nightly run of ${WORKFLOW} on ${SHA:0:10} failed: ${RUN_URL}"
|
||||
number=$(gh issue list --state open --search "in:title \"${title}\"" --json number,title --jq "map(select(.title == \"${title}\")) | .[0].number // empty")
|
||||
if [ -n "$number" ]; then
|
||||
gh issue comment "$number" --body "$body"
|
||||
else
|
||||
gh issue create --title "$title" --body "$body"
|
||||
fi
|
||||
@@ -7,23 +7,62 @@ on:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
# labeled: the "🚀 ready to merge" label starts the full set (see below)
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
# Skip pull requests that change only files no job here reads. The list is checked by
|
||||
# tools/check_path_filters/check_path_filters.py (repository_checks.yml); change both together.
|
||||
paths:
|
||||
- '**'
|
||||
- '!docs/**'
|
||||
- '!**.md'
|
||||
- '!.github/*'
|
||||
- '!.github/ISSUE_TEMPLATE/**'
|
||||
- '!.github/external_ci/**'
|
||||
- '!.github/workflows/**'
|
||||
- '!.reuse/**'
|
||||
- '!LICENSES/**'
|
||||
- '!CITATION.cff'
|
||||
- '!REUSE.toml'
|
||||
# read by tools/check_build_options in the ci_meson_install job (ubuntu.yml)
|
||||
- 'docs/mkdocs/docs/integration/package_managers.md'
|
||||
# built by the swiftpm job (macos.yml)
|
||||
- 'docs/mkdocs/docs/integration/swift/**'
|
||||
- '.github/workflows/windows.yml'
|
||||
schedule:
|
||||
# the nightly set (see below), on develop
|
||||
- cron: '0 2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# A run triggered by any other label gets a group of its own, so it does not
|
||||
# cancel the run of the last push; its jobs are skipped.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'schedule' && 'nightly' || github.ref || github.run_id }}${{ github.event.action == 'labeled' && github.event.label.name != '🚀 ready to merge' && format('-{0}', github.run_id) || '' }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
# The jobs are split into three sets like in ubuntu.yml (see "How CI runs" in
|
||||
# docs/mkdocs/docs/community/quality_assurance.md): the PR set runs on every
|
||||
# push; the full set after the PR set passed, on pushes and on pull requests
|
||||
# with the "🚀 ready to merge" label; the nightly set nightly on develop, on
|
||||
# pushes to master and release/*, and when started by hand. tools/ci_jobs
|
||||
# checks that every job belongs to exactly one set.
|
||||
|
||||
jobs:
|
||||
###########################################################################
|
||||
# PR set
|
||||
###########################################################################
|
||||
|
||||
mingw:
|
||||
if: &pr_set ${{ github.event_name != 'schedule' && (github.event.action != 'labeled' || github.event.label.name == '🚀 ready to merge') }}
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [x64, x86]
|
||||
architecture: [x86]
|
||||
|
||||
steps:
|
||||
steps: &mingw_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -40,15 +79,26 @@ jobs:
|
||||
run: cd build ; ctest -j 10 -C Debug --output-on-failure
|
||||
|
||||
msvc:
|
||||
if: *pr_set
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
architecture: [Win32, x64]
|
||||
std_version: [default, latest]
|
||||
include:
|
||||
- build_type: Debug
|
||||
architecture: x64
|
||||
std_version: default
|
||||
- build_type: Release
|
||||
architecture: x64
|
||||
std_version: default
|
||||
- build_type: Debug
|
||||
architecture: Win32
|
||||
std_version: default
|
||||
- build_type: Release
|
||||
architecture: Win32
|
||||
std_version: latest
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
steps: &msvc_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -77,15 +127,20 @@ jobs:
|
||||
# Visual Studio 2026 (v145 toolset) on the windows-2025 image. The "Visual Studio
|
||||
# 18 2026" generator requires CMake 4.2+, so a recent CMake is fetched explicitly.
|
||||
msvc-vs2026:
|
||||
if: *pr_set
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
architecture: [Win32, x64]
|
||||
std_version: [default, latest]
|
||||
include:
|
||||
- build_type: Debug
|
||||
architecture: x64
|
||||
std_version: latest
|
||||
- build_type: Release
|
||||
architecture: Win32
|
||||
std_version: default
|
||||
|
||||
runs-on: windows-2025
|
||||
|
||||
steps:
|
||||
steps: &msvc_vs2026_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -117,13 +172,14 @@ jobs:
|
||||
# Native ARM64 Windows runner with the MSVC ARM64 toolset. The windows-11-arm
|
||||
# label is only available for public repositories.
|
||||
msvc-arm64:
|
||||
if: *pr_set
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
build_type: [Debug]
|
||||
|
||||
runs-on: windows-11-arm
|
||||
|
||||
steps:
|
||||
steps: &msvc_arm64_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -141,12 +197,13 @@ jobs:
|
||||
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
|
||||
|
||||
clang:
|
||||
if: *pr_set
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
version: [11.0.1, 12.0.1, 13.0.1, 14.0.6, 15.0.7, 16.0.6, 18.1.8, 19.1.7, 20.1.8]
|
||||
version: [20.1.8]
|
||||
|
||||
steps:
|
||||
steps: &clang_steps
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -189,24 +246,8 @@ jobs:
|
||||
- name: Test
|
||||
run: cd build ; ctest -j 10 -C Debug --output-on-failure
|
||||
|
||||
clang-cl:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [Win32, x64]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -T ClangCL -DJSON_BuildTests=On
|
||||
- name: Build
|
||||
run: cmake --build build --config Debug --parallel 10
|
||||
- name: Test
|
||||
run: cd build ; ctest -j 10 -C Debug --output-on-failure
|
||||
|
||||
ci_module_cpp20:
|
||||
if: *pr_set
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -225,4 +266,145 @@ jobs:
|
||||
run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_CI=ON -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /EHsc /W4 /WX"
|
||||
- name: Build
|
||||
run: cmake --build build --config Debug --target ci_module_cpp20
|
||||
|
||||
|
||||
|
||||
|
||||
###########################################################################
|
||||
# full set: starts after the PR set passed
|
||||
###########################################################################
|
||||
|
||||
msvc_full:
|
||||
needs: &pr_set_jobs [mingw, msvc, msvc-vs2026, msvc-arm64, clang, ci_module_cpp20]
|
||||
if: &full_set ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, '🚀 ready to merge') }}
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
architecture: [Win32, x64]
|
||||
std_version: [default, latest]
|
||||
exclude:
|
||||
# in the PR set
|
||||
- build_type: Debug
|
||||
architecture: x64
|
||||
std_version: default
|
||||
- build_type: Release
|
||||
architecture: x64
|
||||
std_version: default
|
||||
- build_type: Debug
|
||||
architecture: Win32
|
||||
std_version: default
|
||||
- build_type: Release
|
||||
architecture: Win32
|
||||
std_version: latest
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
steps: *msvc_steps
|
||||
|
||||
# Visual Studio 2026 (v145 toolset) on the windows-2025 image. The "Visual Studio
|
||||
# 18 2026" generator requires CMake 4.2+, so a recent CMake is fetched explicitly.
|
||||
msvc-vs2026_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
architecture: [Win32, x64]
|
||||
std_version: [default, latest]
|
||||
exclude:
|
||||
# in the PR set
|
||||
- build_type: Debug
|
||||
architecture: x64
|
||||
std_version: latest
|
||||
- build_type: Release
|
||||
architecture: Win32
|
||||
std_version: default
|
||||
|
||||
runs-on: windows-2025
|
||||
|
||||
steps: *msvc_vs2026_steps
|
||||
|
||||
# Native ARM64 Windows runner with the MSVC ARM64 toolset. The windows-11-arm
|
||||
# label is only available for public repositories.
|
||||
msvc-arm64_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Release]
|
||||
|
||||
runs-on: windows-11-arm
|
||||
|
||||
steps: *msvc_arm64_steps
|
||||
|
||||
clang_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
version: [11.0.1, 12.0.1, 13.0.1, 14.0.6, 15.0.7, 16.0.6, 18.1.8, 19.1.7]
|
||||
|
||||
steps: *clang_steps
|
||||
|
||||
clang-cl_full:
|
||||
needs: *pr_set_jobs
|
||||
if: *full_set
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [Win32, x64]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -T ClangCL -DJSON_BuildTests=On
|
||||
- name: Build
|
||||
run: cmake --build build --config Debug --parallel 10
|
||||
- name: Test
|
||||
run: cd build ; ctest -j 10 -C Debug --output-on-failure
|
||||
|
||||
|
||||
###########################################################################
|
||||
# nightly set
|
||||
###########################################################################
|
||||
|
||||
mingw_nightly:
|
||||
if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref != 'refs/heads/develop') }}
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
architecture: [x64]
|
||||
|
||||
steps: *mingw_steps
|
||||
|
||||
# A failure of a scheduled run opens an issue, or comments on the open one.
|
||||
nightly_report:
|
||||
needs: [mingw_nightly]
|
||||
if: ${{ always() && github.event_name == 'schedule' && contains(needs.*.result, 'failure') }}
|
||||
runs-on: ubuntu-26.04
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Open or update the nightly failure issue
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
WORKFLOW: ${{ github.workflow }}
|
||||
SHA: ${{ github.sha }}
|
||||
run: |
|
||||
title="Nightly CI failure (${WORKFLOW})"
|
||||
body="The nightly run of ${WORKFLOW} on ${SHA:0:10} failed: ${RUN_URL}"
|
||||
number=$(gh issue list --state open --search "in:title \"${title}\"" --json number,title --jq "map(select(.title == \"${title}\")) | .[0].number // empty")
|
||||
if [ -n "$number" ]; then
|
||||
gh issue comment "$number" --body "$body"
|
||||
else
|
||||
gh issue create --title "$title" --body "$body"
|
||||
fi
|
||||
@@ -13,6 +13,80 @@ describe each of them.
|
||||
|
||||
<p class="nj-caption" markdown>The checks grouped by the stage at which they run, from push or pull request through the merge into develop to a release. The badge on each card says whether the check runs on every push or PR, on a schedule, or continuously.</p>
|
||||
|
||||
## How CI runs
|
||||
|
||||
Not every job runs for every change. The compiler jobs on Ubuntu, macOS, and Windows are split into three sets, so a
|
||||
pull request gets fast feedback and the long jobs run when they matter:
|
||||
|
||||
| Set | When it runs | What it contains |
|
||||
|-------------|-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| PR set | every push to a pull request, and every push to `develop`, `master`, and `release/*` | GCC and Clang with all warnings, Clang-Tidy, sanitizers, IWYU, cpplint, the oldest and newest GCC and Clang, common CMake options, Meson, Emscripten, four Visual Studio 2022 and two Visual Studio 2026 configurations, MinGW, Clang on Windows, ARM64 Windows, five Xcode versions, Swift Package Manager; with the checks that always run, they would have caught at least 92 % of the failing commits of September and October 2026 |
|
||||
| full set | after the PR set passed: on pull requests with the label :rocket: ready to merge, and on every push | every other compiler, version, C++ standard, and CMake option, the Clang Static Analyzer, Cppcheck, and the C++20 module tests |
|
||||
| nightly set | every night on `develop`, on every push to `master` and `release/*`, and when started by hand | Infer, Valgrind, coverage, the Intel and NVIDIA compilers, CUDA, ARM64 Linux, and 64-bit MinGW; a failure opens an issue |
|
||||
|
||||
The documentation and license checks and the amalgamation check run on every push and pull request; AppVeyor (Visual
|
||||
Studio 2015, 2017, and 2019) has its own schedule. A pull request that changes only the documentation, Markdown files, GitHub metadata, or license files
|
||||
skips the compiler workflows (see [`tools/check_path_filters`](https://github.com/nlohmann/json/tree/develop/tools/check_path_filters)).
|
||||
|
||||
A maintainer adds the label :rocket: ready to merge when a pull request is ready; the full set then runs, and again on
|
||||
every later push to that pull request. A pull request is merged only when the full set passed.
|
||||
|
||||
??? abstract "Jobs of the compiler workflows and their sets"
|
||||
|
||||
The table is generated by [`tools/ci_jobs`](https://github.com/nlohmann/json/tree/develop/tools/ci_jobs), which
|
||||
also checks in CI that it is up to date and that every job belongs to exactly one set.
|
||||
|
||||
<!-- ci_jobs: begin -->
|
||||
| Set | Workflow | Job | Configurations |
|
||||
|-----|----------|-----|----------------|
|
||||
| PR set | macos.yml | `macos-15` | 16.0; 16.4; 26.3 |
|
||||
| PR set | macos.yml | `macos-26` | 26.6 |
|
||||
| PR set | macos.yml | `xcode_standards` | 14 |
|
||||
| PR set | macos.yml | `swiftpm` | - |
|
||||
| PR set | ubuntu.yml | `ci_test_gcc` | - |
|
||||
| PR set | ubuntu.yml | `ci_meson_install` | - |
|
||||
| PR set | ubuntu.yml | `ci_static_analysis_ubuntu` | ci_cpplint |
|
||||
| PR set | ubuntu.yml | `ci_static_analysis_clang` | ci_test_clang; ci_clang_tidy; ci_test_clang_sanitizer; ci_single_binaries |
|
||||
| PR set | ubuntu.yml | `ci_cmake_options` | ci_test_diagnostics; ci_test_diagnostic_positions; ci_test_noexceptions; ci_test_noglobaludls |
|
||||
| PR set | ubuntu.yml | `ci_test_compilers_gcc_old` | 4.8 |
|
||||
| PR set | ubuntu.yml | `ci_test_compilers_clang` | 3.4 |
|
||||
| PR set | ubuntu.yml | `ci_test_standards_gcc` | 26 |
|
||||
| PR set | ubuntu.yml | `ci_test_standards_clang` | 26, libcxx |
|
||||
| PR set | ubuntu.yml | `ci_emscripten` | - |
|
||||
| PR set | windows.yml | `mingw` | x86 |
|
||||
| PR set | windows.yml | `msvc` | Debug, x64, default; Release, x64, default; Debug, Win32, default; Release, Win32, latest |
|
||||
| PR set | windows.yml | `msvc-vs2026` | Debug, x64, latest; Release, Win32, default |
|
||||
| PR set | windows.yml | `msvc-arm64` | Debug |
|
||||
| PR set | windows.yml | `clang` | 20.1.8 |
|
||||
| PR set | windows.yml | `ci_module_cpp20` | - |
|
||||
| full set | macos.yml | `macos-15_full` | 16.1; 16.2; 16.3; 26.0.1; 26.1.1; 26.2 |
|
||||
| full set | macos.yml | `macos-26_full` | 26.4.1; 26.5 |
|
||||
| full set | macos.yml | `xcode_standards_full` | 11; 17; 20; 23; 26 |
|
||||
| full set | ubuntu.yml | `ci_static_analysis_ubuntu_full` | ci_test_single_header; ci_cppcheck; ci_reproducible_tests; ci_non_git_tests; ci_offline_testdata |
|
||||
| full set | ubuntu.yml | `ci_static_analysis_clang_full` | ci_clang_analyze |
|
||||
| full set | ubuntu.yml | `ci_cmake_options_full` | ci_cmake_flags; ci_test_noimplicitconversions; ci_test_legacycomparison; ci_test_disableenumserialization; ci_test_disabletuplereferenceconversion; ci_test_skiplibraryversioncheck; ci_test_simdutf; ci_test_strict_nul_handling; ci_test_delete_deprecated_functions; ci_test_no_thread_local |
|
||||
| full set | ubuntu.yml | `ci_test_compilers_gcc_old_full` | 4.9; 5; 6 |
|
||||
| full set | ubuntu.yml | `ci_test_compilers_gcc_full` | 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; latest |
|
||||
| full set | ubuntu.yml | `ci_test_compilers_clang_full` | 3.5; 3.6; 3.7; 3.8; 3.9; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15-bullseye; 16; 17; 18; 19; 20; 21; 22; latest |
|
||||
| full set | ubuntu.yml | `ci_test_standards_gcc_full` | 11; 14; 17; 20; 23 |
|
||||
| full set | ubuntu.yml | `ci_test_standards_clang_full` | 11, libcxx; 11, libstdcxx; 14, libcxx; 14, libstdcxx; 17, libcxx; 17, libstdcxx; 20, libcxx; 20, libstdcxx; 23, libcxx; 23, libstdcxx; 26, libstdcxx |
|
||||
| full set | ubuntu.yml | `ci_module_cpp20` | gcc:latest; silkeh/clang:latest |
|
||||
| full set | windows.yml | `msvc_full` | Debug, Win32, latest; Debug, x64, latest; Release, Win32, default; Release, x64, latest |
|
||||
| full set | windows.yml | `msvc-vs2026_full` | Debug, Win32, default; Debug, Win32, latest; Debug, x64, default; Release, Win32, latest; Release, x64, default; Release, x64, latest |
|
||||
| full set | windows.yml | `msvc-arm64_full` | Release |
|
||||
| full set | windows.yml | `clang_full` | 11.0.1; 12.0.1; 13.0.1; 14.0.6; 15.0.7; 16.0.6; 18.1.8; 19.1.7 |
|
||||
| full set | windows.yml | `clang-cl_full` | Win32; x64 |
|
||||
| nightly set | ubuntu.yml | `ci_infer` | - |
|
||||
| nightly set | ubuntu.yml | `ci_static_analysis_ubuntu_nightly` | ci_test_valgrind |
|
||||
| nightly set | ubuntu.yml | `ci_test_coverage` | - |
|
||||
| nightly set | ubuntu.yml | `ci_cuda_example` | 11.8.0; 12.1.1; 12.6.3 |
|
||||
| nightly set | ubuntu.yml | `ci_icpc` | - |
|
||||
| nightly set | ubuntu.yml | `ci_icpx` | - |
|
||||
| nightly set | ubuntu.yml | `ci_nvhpc` | - |
|
||||
| nightly set | ubuntu.yml | `ci_test_arm64` | - |
|
||||
| nightly set | windows.yml | `mingw_nightly` | x64 |
|
||||
<!-- ci_jobs: end -->
|
||||
|
||||
## C++ language compliance and compiler compatibility
|
||||
|
||||
!!! success "Requirement: Compiler support"
|
||||
|
||||
@@ -759,14 +759,9 @@ body:has(.nj-hero) .md-content {
|
||||
}
|
||||
}
|
||||
|
||||
/* blog posts: author and date right below the title */
|
||||
.md-typeset .nj-byline { margin: -.8rem 0 1.6rem; font-size: .75rem; color: var(--md-default-fg-color--light); }
|
||||
.md-typeset .nj-byline a { color: inherit; }
|
||||
.md-typeset .nj-byline a:hover { color: var(--md-accent-fg-color); }
|
||||
|
||||
/* figure captions: "Figure N." in bold, close to the figure, set in from the text column; figures and tables are
|
||||
numbered per page, each with its own counter */
|
||||
.md-content__inner { counter-reset: nj-figure nj-table nj-listing; }
|
||||
.md-content__inner { counter-reset: nj-figure nj-table; }
|
||||
.md-typeset :is(.nj-caption, .nj-charts-caption) {
|
||||
max-width: none;
|
||||
margin: .3rem 2rem 1.5rem;
|
||||
@@ -787,25 +782,6 @@ body:has(.nj-hero) .md-content {
|
||||
.md-typeset :is(.nj-caption, .nj-charts-caption) { margin-inline: 1rem; }
|
||||
}
|
||||
|
||||
/* code captions: "Listing N." in bold, directly below the code block, in the figure caption style */
|
||||
.md-typeset .nj-code-caption {
|
||||
max-width: none;
|
||||
margin: -.4rem 2rem 1.5rem;
|
||||
font-size: .75rem;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
.md-typeset .nj-code-caption::before {
|
||||
counter-increment: nj-listing;
|
||||
content: "Listing " counter(nj-listing) ". ";
|
||||
font-weight: 700;
|
||||
color: var(--md-default-fg-color);
|
||||
}
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
.md-typeset .nj-code-caption { margin-inline: 1rem; }
|
||||
}
|
||||
|
||||
/* table captions: "Table N." in bold, directly below the table, in the figure caption style */
|
||||
.md-typeset .nj-table-caption {
|
||||
max-width: none;
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
.md-typeset svg.nj-charts--compile, .md-typeset svg.nj-charts--scaling { max-width: 26rem; }
|
||||
.md-typeset svg.nj-charts--sizes { max-width: 26rem; }
|
||||
/* home/blog/how_3_13_0_got_faster.md (scripts/figures/perf_blog.py) */
|
||||
.md-typeset svg.nj-charts--blog { max-width: 34rem; }
|
||||
.md-typeset svg.nj-charts--swar { max-width: 34rem; }
|
||||
.md-typeset svg.nj-charts--timeline { max-width: 22rem; }
|
||||
|
||||
.nj-charts text { fill: currentColor; font-size: 13px; }
|
||||
.nj-charts .nj-charts-leg { font-size: 13.5px; }
|
||||
@@ -47,34 +43,10 @@
|
||||
paint-order: stroke; stroke: var(--md-default-bg-color); stroke-width: 4px; stroke-linejoin: round; }
|
||||
.nj-charts .nj-charts-factor { fill: var(--nj-charts-ink2); font-size: 12px; font-weight: 600; text-anchor: middle; }
|
||||
.nj-charts .nj-charts-note { fill: var(--nj-charts-ink2); font-size: 12px; }
|
||||
/* heatmap cells (perf_blog_usecases_*.svg): green for the fastest, gray around twice the time, red for the slowest;
|
||||
adjacent steps checked for CVD separation on the light and the slate surface; the numbers are in every cell */
|
||||
.md-typeset svg.nj-charts--heat { max-width: 49rem; }
|
||||
.nj-charts--heat { --nj-heat-0: #3fa557; --nj-heat-1: #8bcc95; --nj-heat-2: #ebeae6; --nj-heat-3: #f2ae9b;
|
||||
--nj-heat-4: #dc5a43; --nj-heat-ink: #1b1b1b; --nj-heat-ink-strong: #1b1b1b; }
|
||||
[data-md-color-scheme="slate"] .nj-charts--heat { --nj-heat-0: #3a9d50; --nj-heat-1: #2c6b3a; --nj-heat-2: #33353a;
|
||||
--nj-heat-3: #8a3f2e; --nj-heat-4: #d95b3a; --nj-heat-ink: #e8e8e6; --nj-heat-ink-strong: #141414; }
|
||||
.nj-charts .nj-heat-0 { fill: var(--nj-heat-0); }
|
||||
.nj-charts .nj-heat-1 { fill: var(--nj-heat-1); }
|
||||
.nj-charts .nj-heat-2 { fill: var(--nj-heat-2); }
|
||||
.nj-charts .nj-heat-3 { fill: var(--nj-heat-3); }
|
||||
.nj-charts .nj-heat-4 { fill: var(--nj-heat-4); }
|
||||
.nj-charts .nj-heat-na { fill: none; stroke: var(--nj-charts-grid); stroke-width: 1; }
|
||||
.nj-charts .nj-charts-cell { fill: var(--nj-heat-ink); font-size: 12px; font-variant-numeric: tabular-nums; }
|
||||
.nj-charts :is(.nj-heat-0, .nj-heat-4) ~ .nj-charts-cell { fill: var(--nj-heat-ink-strong); }
|
||||
.nj-charts .nj-charts-cell--small { font-size: 10.5px; }
|
||||
.nj-charts .nj-heat-cell { cursor: default; outline: none; }
|
||||
.nj-charts .nj-heat-cell:is(:hover, :focus-visible, .nj-heat-on) rect { stroke: var(--md-default-fg-color); stroke-width: 1.5; }
|
||||
.nj-heat-tip { position: absolute; z-index: 5; max-width: 24rem; padding: .5rem .7rem; border-radius: 6px;
|
||||
background: var(--md-default-bg-color); color: var(--md-default-fg-color);
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, .25); font-size: .68rem; line-height: 1.45; pointer-events: none; }
|
||||
.nj-heat-tip strong { display: block; margin-bottom: .2rem; }
|
||||
.nj-heat-tip[hidden] { display: none; }
|
||||
|
||||
.nj-charts .nj-charts-grid { stroke: var(--nj-charts-grid); stroke-width: 1; }
|
||||
.nj-charts .nj-charts-zero, .nj-charts .nj-charts-axis { stroke: var(--nj-charts-base); stroke-width: 1.5; }
|
||||
.nj-charts .nj-charts-ref { stroke: currentColor; stroke-width: 1.5; }
|
||||
.nj-charts .nj-charts-head { fill: var(--nj-charts-base); }
|
||||
|
||||
.nj-charts .nj-charts-c1 { fill: var(--nj-charts-c1); }
|
||||
.nj-charts .nj-charts-c2 { fill: var(--nj-charts-c2); }
|
||||
@@ -168,19 +140,3 @@
|
||||
/* direct line labels replace the legend */
|
||||
.nj-charts .nj-charts-name-json { fill: var(--nj-charts-json-c); font-weight: 600; }
|
||||
.nj-charts .nj-charts-name-ojson { fill: var(--nj-charts-ojson-c); font-weight: 600; }
|
||||
|
||||
/* theme badges of home/blog/how_3_13_0_got_faster.md: the number of one of the eight themes, as a digit in a blue
|
||||
circle, in headings, text, tables and the timeline figures (nj-theme-dot); "U" and other marks are gray */
|
||||
.md-typeset .nj-theme { display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
|
||||
min-width: 1.45em; height: 1.45em; padding: 0 .3em; border-radius: .725em; vertical-align: .08em;
|
||||
background: var(--nj-blue); color: var(--md-default-bg-color); font-size: .78em; font-weight: 700; line-height: 1;
|
||||
font-variant-numeric: tabular-nums; text-decoration: none; }
|
||||
.md-typeset a.nj-theme:is(:hover, :focus-visible) { background: var(--nj-blue-deep); color: var(--md-default-bg-color); }
|
||||
.md-typeset .nj-theme--other { background: var(--md-default-fg-color--light); }
|
||||
.md-typeset h2 .nj-theme { margin-right: .35em; vertical-align: .12em; }
|
||||
.md-typeset .nj-theme-list > ul { list-style: none; margin-left: 0; }
|
||||
.md-typeset .nj-theme-list > ul > li { margin-left: 0; padding-left: 2em; text-indent: -2em; }
|
||||
.md-typeset .nj-theme-list > ul > li > .nj-theme { margin-right: .55em; text-indent: 0; }
|
||||
.nj-charts .nj-theme-dot { fill: var(--nj-blue); }
|
||||
.nj-charts .nj-theme-dot--other { fill: var(--nj-charts-ink2); }
|
||||
.nj-charts .nj-theme-num { fill: var(--md-default-bg-color); font-size: 11px; font-weight: 700; }
|
||||
@@ -17,16 +17,16 @@
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M76 115 L106 115" marker-end="url(#jvl-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="108" y="98" width="84" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono" x="150" y="120" text-anchor="middle" xml:space="preserve">std::map</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 L226 67" marker-end="url(#jvl-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 C192 115 226 67 226 67" marker-end="url(#jvl-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="228" y="50" width="180" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-key" x="240" y="72" xml:space="preserve">"port"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-num" x="396" y="72" text-anchor="end" xml:space="preserve">6379</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 L226 115" marker-end="url(#jvl-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 C192 115 226 115 226 115" marker-end="url(#jvl-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="228" y="98" width="180" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-key" x="240" y="120" xml:space="preserve">"price"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-num" x="396" y="120" text-anchor="end" xml:space="preserve">19.9</text>
|
||||
<text class="nj-jsonview-note" x="418" y="120" xml:space="preserve">double: 19.90 is gone</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 L226 163" marker-end="url(#jvl-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 C192 115 226 163 226 163" marker-end="url(#jvl-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="228" y="146" width="180" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-key" x="240" y="168" xml:space="preserve">"tags"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-line" x="396" y="168" text-anchor="end" xml:space="preserve">•</text>
|
||||
@@ -38,8 +38,8 @@
|
||||
<path class="nj-jsonview-sep" d="M624 146 V180"/>
|
||||
<text class="nj-jsonview-mono" x="601" y="168" text-anchor="middle" xml:space="preserve">json</text>
|
||||
<text class="nj-jsonview-mono" x="647" y="168" text-anchor="middle" xml:space="preserve">json</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M601 146 C601 130 641 130 706 130" marker-end="url(#jvl-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M647 180 C647 196 687 196 706 196" marker-end="url(#jvl-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M601 146 C601 126 706 150 706 130" marker-end="url(#jvl-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M647 180 C647 200 706 176 706 196" marker-end="url(#jvl-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="708" y="113" width="126" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm nj-jsonview-c-str" x="771" y="135" text-anchor="middle" xml:space="preserve">std::string eu</text>
|
||||
<rect class="nj-jsonview-heap" x="708" y="179" width="126" height="34" rx="5"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -1,148 +0,0 @@
|
||||
<svg class="nj-fig nj-jsonview " viewBox="0 0 840 456" role="img" aria-labelledby="fig-jvli-title fig-jvli-title-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-jvli-title">The same J​SON text parsed by json_document::parse()</title>
|
||||
<desc id="fig-jvli-title-d">The same text parsed by json_document::parse(): it keeps the 54 bytes of source text and builds a flat index of nine 16-byte nodes in document order: object, key port, unsigned integer 6379 (the converted value is in the node), key price, float, key tags, array, string eu, and an escaped string. Keys, the float, and the plain string point back into the source text; the escaped string points into the document's buffer of decoded strings. A json_view is two pointers: one to the document and one to a node, here the array.</desc>
|
||||
<defs>
|
||||
<marker id="jvli-line" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-line nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-str" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-str nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-key" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-key nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-num" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-num nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-dec" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-dec nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-own" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-own nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-struct" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-struct nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvli-bad" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-bad nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
</defs>
|
||||
<g transform="translate(0 -236)">
|
||||
<text class="nj-jsonview-h" x="16" y="262" xml:space="preserve">json_document::parse(): the source text stays where it is; one flat index of 16-byte nodes</text>
|
||||
<text class="nj-jsonview-note" x="16" y="290" xml:space="preserve">source text, 54 bytes (borrowed, or owned by the document)</text>
|
||||
<rect class="nj-jsonview-ribbon" x="42" y="300" width="756" height="26" rx="4"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-key" x="71" y="302" width="54" height="22" rx="3"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-num" x="169" y="302" width="54" height="22" rx="3"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-key" x="267" y="302" width="68" height="22" rx="3"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-num" x="379" y="302" width="68" height="22" rx="3"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-key" x="491" y="302" width="54" height="22" rx="3"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-str" x="617" y="302" width="26" height="22" rx="3"/>
|
||||
<rect class="nj-jsonview-span nj-jsonview-c-dec" x="701" y="302" width="54" height="22" rx="3"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="49" y="317.5" text-anchor="middle" xml:space="preserve">{</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="63" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="77" y="317.5" text-anchor="middle" xml:space="preserve">p</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="91" y="317.5" text-anchor="middle" xml:space="preserve">o</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="105" y="317.5" text-anchor="middle" xml:space="preserve">r</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="119" y="317.5" text-anchor="middle" xml:space="preserve">t</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="133" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="147" y="317.5" text-anchor="middle" xml:space="preserve">:</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="175" y="317.5" text-anchor="middle" xml:space="preserve">6</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="189" y="317.5" text-anchor="middle" xml:space="preserve">3</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="203" y="317.5" text-anchor="middle" xml:space="preserve">7</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="217" y="317.5" text-anchor="middle" xml:space="preserve">9</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="231" y="317.5" text-anchor="middle" xml:space="preserve">,</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="259" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="273" y="317.5" text-anchor="middle" xml:space="preserve">p</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="287" y="317.5" text-anchor="middle" xml:space="preserve">r</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="301" y="317.5" text-anchor="middle" xml:space="preserve">i</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="315" y="317.5" text-anchor="middle" xml:space="preserve">c</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="329" y="317.5" text-anchor="middle" xml:space="preserve">e</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="343" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="357" y="317.5" text-anchor="middle" xml:space="preserve">:</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="385" y="317.5" text-anchor="middle" xml:space="preserve">1</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="399" y="317.5" text-anchor="middle" xml:space="preserve">9</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="413" y="317.5" text-anchor="middle" xml:space="preserve">.</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="427" y="317.5" text-anchor="middle" xml:space="preserve">9</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="441" y="317.5" text-anchor="middle" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="455" y="317.5" text-anchor="middle" xml:space="preserve">,</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="483" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="497" y="317.5" text-anchor="middle" xml:space="preserve">t</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="511" y="317.5" text-anchor="middle" xml:space="preserve">a</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="525" y="317.5" text-anchor="middle" xml:space="preserve">g</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="539" y="317.5" text-anchor="middle" xml:space="preserve">s</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="553" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="567" y="317.5" text-anchor="middle" xml:space="preserve">:</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="595" y="317.5" text-anchor="middle" xml:space="preserve">[</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="609" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="623" y="317.5" text-anchor="middle" xml:space="preserve">e</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="637" y="317.5" text-anchor="middle" xml:space="preserve">u</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="651" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="665" y="317.5" text-anchor="middle" xml:space="preserve">,</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="693" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="707" y="317.5" text-anchor="middle" xml:space="preserve">a</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="721" y="317.5" text-anchor="middle" xml:space="preserve">\</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="735" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="749" y="317.5" text-anchor="middle" xml:space="preserve">b</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="763" y="317.5" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="777" y="317.5" text-anchor="middle" xml:space="preserve">]</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-byte" x="791" y="317.5" text-anchor="middle" xml:space="preserve">}</text>
|
||||
<text class="nj-jsonview-tiny" x="49" y="340" text-anchor="middle" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-tiny" x="189" y="340" text-anchor="middle" xml:space="preserve">10</text>
|
||||
<text class="nj-jsonview-tiny" x="329" y="340" text-anchor="middle" xml:space="preserve">20</text>
|
||||
<text class="nj-jsonview-tiny" x="469" y="340" text-anchor="middle" xml:space="preserve">30</text>
|
||||
<text class="nj-jsonview-tiny" x="609" y="340" text-anchor="middle" xml:space="preserve">40</text>
|
||||
<text class="nj-jsonview-tiny" x="749" y="340" text-anchor="middle" xml:space="preserve">50</text>
|
||||
<rect class="nj-jsonview-frame" x="16" y="366" width="808" height="254" rx="10"/>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong" x="30" y="602" xml:space="preserve">json_document: owns the node index and the buffer of decoded strings</text>
|
||||
<text class="nj-jsonview-note" x="30" y="500" xml:space="preserve">node index: 9 nodes × 16 bytes = 144 bytes, in document order</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="36" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="42" y="420" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-struct" x="78" y="434" text-anchor="middle" xml:space="preserve">object</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="78" y="451" text-anchor="middle" xml:space="preserve">len 3</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="78" y="465" text-anchor="middle" xml:space="preserve">next 9</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="124" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="130" y="420" xml:space="preserve">1</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-key" x="166" y="434" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="166" y="451" text-anchor="middle" xml:space="preserve">off 2</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="166" y="465" text-anchor="middle" xml:space="preserve">len 4</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-key" d="M166 406 C166 367 98 367 98 328" marker-end="url(#jvli-key)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="212" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="218" y="420" xml:space="preserve">2</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-num" x="254" y="434" text-anchor="middle" xml:space="preserve">uint</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="254" y="451" text-anchor="middle" xml:space="preserve">6379</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="254" y="465" text-anchor="middle" xml:space="preserve">(converted)</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="300" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="306" y="420" xml:space="preserve">3</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-key" x="342" y="434" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="342" y="451" text-anchor="middle" xml:space="preserve">off 16</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="342" y="465" text-anchor="middle" xml:space="preserve">len 5</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-key" d="M342 406 C342 367 301 367 301 328" marker-end="url(#jvli-key)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="388" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="394" y="420" xml:space="preserve">4</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-num" x="430" y="434" text-anchor="middle" xml:space="preserve">float</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="430" y="451" text-anchor="middle" xml:space="preserve">off 24</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="430" y="465" text-anchor="middle" xml:space="preserve">len 5</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-num" d="M430 406 C430 367 413 367 413 328" marker-end="url(#jvli-num)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="476" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="482" y="420" xml:space="preserve">5</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-key" x="518" y="434" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="518" y="451" text-anchor="middle" xml:space="preserve">off 32</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="518" y="465" text-anchor="middle" xml:space="preserve">len 4</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-key" d="M518 406 C518 367 518 367 518 328" marker-end="url(#jvli-key)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="564" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="570" y="420" xml:space="preserve">6</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-struct" x="606" y="434" text-anchor="middle" xml:space="preserve">array</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="606" y="451" text-anchor="middle" xml:space="preserve">len 2</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="606" y="465" text-anchor="middle" xml:space="preserve">next 3</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-str" x="652" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="658" y="420" xml:space="preserve">7</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-str" x="694" y="434" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="694" y="451" text-anchor="middle" xml:space="preserve">off 41</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="694" y="465" text-anchor="middle" xml:space="preserve">len 2</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-str" d="M694 406 C694 367 630 367 630 328" marker-end="url(#jvli-str)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-dec" x="740" y="406" width="84" height="68" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="746" y="420" xml:space="preserve">8</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-c-dec" x="782" y="434" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="782" y="451" text-anchor="middle" xml:space="preserve">escaped</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="782" y="465" text-anchor="middle" xml:space="preserve">len 3</text>
|
||||
<text class="nj-jsonview-note" x="773" y="568" text-anchor="middle" xml:space="preserve">decoded strings</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-dec" x="740" y="518" width="66" height="30" rx="4"/>
|
||||
<text class="nj-jsonview-mono" x="751" y="538" text-anchor="middle" xml:space="preserve">a</text>
|
||||
<text class="nj-jsonview-mono" x="773" y="538" text-anchor="middle" xml:space="preserve">"</text>
|
||||
<text class="nj-jsonview-mono" x="795" y="538" text-anchor="middle" xml:space="preserve">b</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-dec" d="M782 474 C782 496 773 496 773 518" marker-end="url(#jvli-dec)"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="470" y="670" text-anchor="end" xml:space="preserve">json_view v = doc.root()["tags"]</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="480" y="648" width="140" height="34" rx="6"/>
|
||||
<path class="nj-jsonview-sep" d="M550 648 V682"/>
|
||||
<text class="nj-jsonview-mono" x="515" y="670" text-anchor="middle" xml:space="preserve">doc*</text>
|
||||
<text class="nj-jsonview-mono" x="585" y="670" text-anchor="middle" xml:space="preserve">node*</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-struct" d="M515 648 L515 622" marker-end="url(#jvli-struct)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-struct" d="M585 648 C585 561 606 561 606 474" marker-end="url(#jvli-struct)"/>
|
||||
<text class="nj-jsonview-note" x="30" y="524" xml:space="preserve">integers are converted while parsing and kept in their node;</text>
|
||||
<text class="nj-jsonview-note" x="30" y="542" xml:space="preserve">floats and strings point back into the text</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 17 KiB |
@@ -1,49 +0,0 @@
|
||||
<svg class="nj-fig nj-jsonview " viewBox="0 0 840 222" role="img" aria-labelledby="fig-jvlt-title fig-jvlt-title-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-jvlt-title">A J​SON text parsed by basic_json::parse()</title>
|
||||
<desc id="fig-jvlt-title-d">The text {"port": 6379, "price": 19.90, "tags": ["eu", "a\"b"]} parsed by basic_json::parse(): the root json value points to a std::map whose three nodes are separate heap allocations; the price is stored as the double 19.9; the tags array is a std::vector of two json values, each pointing to its own std::string.</desc>
|
||||
<defs>
|
||||
<marker id="jvlt-line" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-line nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-str" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-str nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-key" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-key nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-num" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-num nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-dec" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-dec nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-own" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-own nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-struct" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-struct nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jvlt-bad" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-bad nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
</defs>
|
||||
<text class="nj-jsonview-h" x="16" y="26" xml:space="preserve">basic_json::parse(): a tree, every array, object, and string in its own heap allocation</text>
|
||||
<rect class="nj-jsonview-box" x="16" y="98" width="60" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono" x="46" y="120" text-anchor="middle" xml:space="preserve">json</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M76 115 L106 115" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="108" y="98" width="84" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono" x="150" y="120" text-anchor="middle" xml:space="preserve">std::map</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 L226 67" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="228" y="50" width="180" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-key" x="240" y="72" xml:space="preserve">"port"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-num" x="396" y="72" text-anchor="end" xml:space="preserve">6379</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 L226 115" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="228" y="98" width="180" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-key" x="240" y="120" xml:space="preserve">"price"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-num" x="396" y="120" text-anchor="end" xml:space="preserve">19.9</text>
|
||||
<text class="nj-jsonview-note" x="418" y="120" xml:space="preserve">double: 19.90 is gone</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M192 115 L226 163" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="228" y="146" width="180" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-key" x="240" y="168" xml:space="preserve">"tags"</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-c-line" x="396" y="168" text-anchor="end" xml:space="preserve">•</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M408 163 L442 163" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="444" y="146" width="104" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono" x="496" y="168" text-anchor="middle" xml:space="preserve">std::vector</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M548 163 L576 163" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="578" y="146" width="92" height="34" rx="5"/>
|
||||
<path class="nj-jsonview-sep" d="M624 146 V180"/>
|
||||
<text class="nj-jsonview-mono" x="601" y="168" text-anchor="middle" xml:space="preserve">json</text>
|
||||
<text class="nj-jsonview-mono" x="647" y="168" text-anchor="middle" xml:space="preserve">json</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M601 146 C601 130 641 130 706 130" marker-end="url(#jvlt-line)"/>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-line" d="M647 180 C647 196 687 196 706 196" marker-end="url(#jvlt-line)"/>
|
||||
<rect class="nj-jsonview-heap" x="708" y="113" width="126" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm nj-jsonview-c-str" x="771" y="135" text-anchor="middle" xml:space="preserve">std::string eu</text>
|
||||
<rect class="nj-jsonview-heap" x="708" y="179" width="126" height="34" rx="5"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm nj-jsonview-c-str" x="771" y="201" text-anchor="middle" xml:space="preserve">std::string a"b</text>
|
||||
<rect class="nj-jsonview-heap" x="16" y="186" width="18" height="14" rx="3"/>
|
||||
<text class="nj-jsonview-note" x="42" y="198" xml:space="preserve">a separate heap allocation</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -1,69 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog" viewBox="0 0 600 380" role="img" aria-labelledby="nj-blog-cliffs nj-blog-cliffs-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-cliffs">Operations that grew quadratically or worse: time with 3.12.0 and 3.13.0, log scale</title>
|
||||
<desc id="nj-blog-cliffs-d">Dot plot on a logarithmic time axis, less is better; an arrow leads from each 3.12.0 time to the 3.13.0 time. diff() 64k numbers vs []: 4237 ms to 10.8 ms; diff() 20k objects vs half: 122 ms to 4.13 ms; parse() callback, 32k objects: 1398 ms to 12.1 ms; operator< nested 24 deep: 64.4 ms to 0.002 ms; operator< citm, 10x: 284 ms to 3.94 ms; flatten() citm, ordered_json: 271 ms to 1.45 ms; to_bson() 200 deep, 100x: 20.3 ms to 0.352 ms; push_back() 100k, diagnostics: 1589 ms to 5.32 ms; at(i) 10k, diagnostics: 45.9 ms to 0.088 ms.</desc>
|
||||
<line class="nj-charts-grid" x1="250" y1="30" x2="250" y2="336"/>
|
||||
<text class="nj-charts-tick" x="250" y="352">1 µs</text>
|
||||
<line class="nj-charts-grid" x1="297.857" y1="30" x2="297.857" y2="336"/>
|
||||
<text class="nj-charts-tick" x="297.857" y="352">10 µs</text>
|
||||
<line class="nj-charts-grid" x1="345.714" y1="30" x2="345.714" y2="336"/>
|
||||
<text class="nj-charts-tick" x="345.714" y="352">0.1 ms</text>
|
||||
<line class="nj-charts-grid" x1="393.571" y1="30" x2="393.571" y2="336"/>
|
||||
<text class="nj-charts-tick" x="393.571" y="352">1 ms</text>
|
||||
<line class="nj-charts-grid" x1="441.429" y1="30" x2="441.429" y2="336"/>
|
||||
<text class="nj-charts-tick" x="441.429" y="352">10 ms</text>
|
||||
<line class="nj-charts-grid" x1="489.286" y1="30" x2="489.286" y2="336"/>
|
||||
<text class="nj-charts-tick" x="489.286" y="352">0.1 s</text>
|
||||
<line class="nj-charts-grid" x1="537.143" y1="30" x2="537.143" y2="336"/>
|
||||
<text class="nj-charts-tick" x="537.143" y="352">1 s</text>
|
||||
<line class="nj-charts-grid" x1="585" y1="30" x2="585" y2="336"/>
|
||||
<text class="nj-charts-tick" x="585" y="352">10 s</text>
|
||||
<text class="nj-charts-tick" x="417.5" y="370">runtime (log scale), less is better</text>
|
||||
<defs><marker id="nj-blog-cliffs-head" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="5" markerHeight="5" orient="auto"><path class="nj-charts-head" d="M0 0 L10 5 L0 10 z"/></marker></defs>
|
||||
<circle class="nj-charts-ojson-dot" cx="250" cy="14" r="5"/><text class="nj-charts-leg" x="260" y="18.5">3.12.0</text>
|
||||
<circle class="nj-charts-json-dot" cx="330" cy="14" r="5"/><text class="nj-charts-leg" x="340" y="18.5">3.13.0</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="52" text-anchor="end">diff() 64k numbers vs []</text>
|
||||
<line class="nj-charts-axis" x1="561.152" y1="48" x2="450.028" y2="48" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="567.152" cy="48" r="5"><title>diff() 64k numbers vs [], 3.12.0: 4237 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="443.028" cy="48" r="5"><title>diff() 64k numbers vs [], 3.13.0: 10.8 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="505.09" y="41">392×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="86" text-anchor="end">diff() 20k objects vs half</text>
|
||||
<line class="nj-charts-axis" x1="487.419" y1="82" x2="430.049" y2="82" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="493.419" cy="82" r="5"><title>diff() 20k objects vs half, 3.12.0: 122 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="423.049" cy="82" r="5"><title>diff() 20k objects vs half, 3.13.0: 4.13 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="458.234" y="75">30×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="120" text-anchor="end">parse() callback, 32k objects</text>
|
||||
<line class="nj-charts-axis" x1="538.106" y1="116" x2="452.39" y2="116" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="544.106" cy="116" r="5"><title>parse() callback, 32k objects, 3.12.0: 1398 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="445.39" cy="116" r="5"><title>parse() callback, 32k objects, 3.13.0: 12.1 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="494.748" y="109">116×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="154" text-anchor="end">operator< nested 24 deep</text>
|
||||
<line class="nj-charts-axis" x1="474.14" y1="150" x2="271.406" y2="150" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="480.14" cy="150" r="5"><title>operator< nested 24 deep, 3.12.0: 64.4 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="264.406" cy="150" r="5"><title>operator< nested 24 deep, 3.13.0: 0.002 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="372.273" y="143">32200×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="188" text-anchor="end">operator< citm, 10x</text>
|
||||
<line class="nj-charts-axis" x1="504.98" y1="184" x2="429.07" y2="184" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="510.98" cy="184" r="5"><title>operator< citm, 10x, 3.12.0: 284 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="422.07" cy="184" r="5"><title>operator< citm, 10x, 3.13.0: 3.94 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="466.525" y="177">72×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="222" text-anchor="end">flatten() citm, ordered_json</text>
|
||||
<line class="nj-charts-axis" x1="504.006" y1="218" x2="408.294" y2="218" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="510.006" cy="218" r="5"><title>flatten() citm, ordered_json, 3.12.0: 271 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="401.294" cy="218" r="5"><title>flatten() citm, ordered_json, 3.13.0: 1.45 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="455.65" y="211">187×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="256" text-anchor="end">to_bson() 200 deep, 100x</text>
|
||||
<line class="nj-charts-axis" x1="450.144" y1="252" x2="378.87" y2="252" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="456.144" cy="252" r="5"><title>to_bson() 200 deep, 100x, 3.12.0: 20.3 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="371.87" cy="252" r="5"><title>to_bson() 200 deep, 100x, 3.13.0: 0.352 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="414.007" y="245">58×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="290" text-anchor="end">push_back() 100k, diagnostics</text>
|
||||
<line class="nj-charts-axis" x1="540.768" y1="286" x2="435.311" y2="286" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="546.768" cy="286" r="5"><title>push_back() 100k, diagnostics, 3.12.0: 1589 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="428.311" cy="286" r="5"><title>push_back() 100k, diagnostics, 3.13.0: 5.32 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="487.54" y="279">299×</text>
|
||||
<text class="nj-charts-rowlabel" x="240" y="324" text-anchor="end">at(i) 10k, diagnostics</text>
|
||||
<line class="nj-charts-axis" x1="467.101" y1="320" x2="350.057" y2="320" marker-end="url(#nj-blog-cliffs-head)"/>
|
||||
<circle class="nj-charts-ojson-dot" cx="473.101" cy="320" r="5"><title>at(i) 10k, diagnostics, 3.12.0: 45.9 ms</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="343.057" cy="320" r="5"><title>at(i) 10k, diagnostics, 3.13.0: 0.088 ms</title></circle>
|
||||
<text class="nj-charts-factor" x="408.079" y="313">522×</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.2 KiB |
@@ -1,66 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--swar" viewBox="0 0 600 430" role="img" aria-labelledby="nj-blog-digits nj-blog-digits-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-digits">Converting eight A​SCII digits to their value with three multiplications</title>
|
||||
<desc id="nj-blog-digits-d">The text 12345678 as one word. Masking gives the digit values 1 to 8, one per byte. Multiplying by 10 times 2 to the 8 plus 1 and shifting gives 12, 34, 56 and 78 in 16-bit lanes; multiplying by 100 times 2 to the 16 plus 1 gives 1234 and 5678 in 32-bit lanes; multiplying by 10000 times 2 to the 32 plus 1 gives 12345678.</desc>
|
||||
<text class="fg-h" x="40" y="20">eight A​SCII digits in one 64-bit word (byte 0 is the lowest)</text>
|
||||
<rect class="fg-cell" x="40" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="69" y="53" text-anchor="middle">1</text>
|
||||
<text class="nj-charts-tick" x="69" y="80">0x31</text>
|
||||
<rect class="fg-cell" x="104" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="133" y="53" text-anchor="middle">2</text>
|
||||
<text class="nj-charts-tick" x="133" y="80">0x32</text>
|
||||
<rect class="fg-cell" x="168" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="197" y="53" text-anchor="middle">3</text>
|
||||
<text class="nj-charts-tick" x="197" y="80">0x33</text>
|
||||
<rect class="fg-cell" x="232" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="261" y="53" text-anchor="middle">4</text>
|
||||
<text class="nj-charts-tick" x="261" y="80">0x34</text>
|
||||
<rect class="fg-cell" x="296" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="325" y="53" text-anchor="middle">5</text>
|
||||
<text class="nj-charts-tick" x="325" y="80">0x35</text>
|
||||
<rect class="fg-cell" x="360" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="389" y="53" text-anchor="middle">6</text>
|
||||
<text class="nj-charts-tick" x="389" y="80">0x36</text>
|
||||
<rect class="fg-cell" x="424" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="453" y="53" text-anchor="middle">7</text>
|
||||
<text class="nj-charts-tick" x="453" y="80">0x37</text>
|
||||
<rect class="fg-cell" x="488" y="30" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="517" y="53" text-anchor="middle">8</text>
|
||||
<text class="nj-charts-tick" x="517" y="80">0x38</text>
|
||||
<text class="fg-h" x="40" y="112">& 0x0F0F0F0F0F0F0F0F: one digit value per byte</text>
|
||||
<rect class="fg-cell" x="40" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="69" y="145" text-anchor="middle">1</text>
|
||||
<rect class="fg-cell" x="104" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="133" y="145" text-anchor="middle">2</text>
|
||||
<rect class="fg-cell" x="168" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="197" y="145" text-anchor="middle">3</text>
|
||||
<rect class="fg-cell" x="232" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="261" y="145" text-anchor="middle">4</text>
|
||||
<rect class="fg-cell" x="296" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="325" y="145" text-anchor="middle">5</text>
|
||||
<rect class="fg-cell" x="360" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="389" y="145" text-anchor="middle">6</text>
|
||||
<rect class="fg-cell" x="424" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="453" y="145" text-anchor="middle">7</text>
|
||||
<rect class="fg-cell" x="488" y="122" width="58" height="34" rx="4"/>
|
||||
<text class="fg-code" x="517" y="145" text-anchor="middle">8</text>
|
||||
<text class="fg-h" x="40" y="186">× (10 · 2⁸ + 1) >> 8, every second byte kept: two digits per 16 bits</text>
|
||||
<rect class="fg-cell" x="40" y="196" width="122" height="34" rx="4"/>
|
||||
<text class="fg-code" x="101" y="219" text-anchor="middle">12</text>
|
||||
<rect class="fg-cell" x="168" y="196" width="122" height="34" rx="4"/>
|
||||
<text class="fg-code" x="229" y="219" text-anchor="middle">34</text>
|
||||
<rect class="fg-cell" x="296" y="196" width="122" height="34" rx="4"/>
|
||||
<text class="fg-code" x="357" y="219" text-anchor="middle">56</text>
|
||||
<rect class="fg-cell" x="424" y="196" width="122" height="34" rx="4"/>
|
||||
<text class="fg-code" x="485" y="219" text-anchor="middle">78</text>
|
||||
<text class="fg-h" x="40" y="260">× (100 · 2¹⁶ + 1) >> 16, every second lane kept: four digits per 32 bits</text>
|
||||
<rect class="fg-cell" x="40" y="270" width="250" height="34" rx="4"/>
|
||||
<text class="fg-code" x="165" y="293" text-anchor="middle">1234</text>
|
||||
<rect class="fg-cell" x="296" y="270" width="250" height="34" rx="4"/>
|
||||
<text class="fg-code" x="421" y="293" text-anchor="middle">5678</text>
|
||||
<text class="fg-h" x="40" y="334">× (10000 · 2³² + 1) >> 32: the value</text>
|
||||
<rect class="fg-cell" x="40" y="344" width="506" height="34" rx="4"/>
|
||||
<rect class="nj-charts-c1" fill-opacity=".25" x="40" y="344" width="506" height="34" rx="4"/>
|
||||
<text class="fg-code" x="293" y="367" text-anchor="middle">12345678</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="400">Each step combines neighboring lanes, in all lanes of the word at once:</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="418">three multiplications instead of eight, and no branch.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -1,36 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog" viewBox="0 0 560 250" role="img" aria-labelledby="nj-blog-dist nj-blog-dist-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-dist">Speedup of 3.13.0 over 3.12.0 for all 182 benchmarks of the suite</title>
|
||||
<desc id="nj-blog-dist-d">Bars counting the benchmarks per speedup range: below 1x: 1; 1 to 1.5x: 22; 1.5 to 2x: 12; 2 to 3x: 60; 3 to 5x: 58; 5 to 10x: 25; 10x or more: 4. Median 2.9x, geometric mean 3.0x.</desc>
|
||||
<line class="nj-charts-grid" x1="52" y1="196" x2="548" y2="196"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="46" y="200">0</text>
|
||||
<line class="nj-charts-grid" x1="52" y1="144.571" x2="548" y2="144.571"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="46" y="148.571">20</text>
|
||||
<line class="nj-charts-grid" x1="52" y1="93.1429" x2="548" y2="93.1429"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="46" y="97.1429">40</text>
|
||||
<line class="nj-charts-grid" x1="52" y1="41.7143" x2="548" y2="41.7143"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="46" y="45.7143">60</text>
|
||||
<rect class="nj-charts-c2" x="60.0" y="193.4" width="54.9" height="2.6" rx="3"><title>below 1×: 1</title></rect>
|
||||
<text class="nj-charts-val" x="87.4" y="188.4" text-anchor="middle">1</text>
|
||||
<text class="nj-charts-tick" x="87.4" y="212.0">below 1×</text>
|
||||
<rect class="nj-charts-c1" x="130.9" y="139.4" width="54.9" height="56.6" rx="3"><title>1 to 1.5×: 22</title></rect>
|
||||
<text class="nj-charts-val" x="158.3" y="134.4" text-anchor="middle">22</text>
|
||||
<text class="nj-charts-tick" x="158.3" y="212.0">1 to 1.5×</text>
|
||||
<rect class="nj-charts-c1" x="201.7" y="165.1" width="54.9" height="30.9" rx="3"><title>1.5 to 2×: 12</title></rect>
|
||||
<text class="nj-charts-val" x="229.1" y="160.1" text-anchor="middle">12</text>
|
||||
<text class="nj-charts-tick" x="229.1" y="212.0">1.5 to 2×</text>
|
||||
<rect class="nj-charts-c1" x="272.6" y="41.7" width="54.9" height="154.3" rx="3"><title>2 to 3×: 60</title></rect>
|
||||
<text class="nj-charts-val" x="300.0" y="36.7" text-anchor="middle">60</text>
|
||||
<text class="nj-charts-tick" x="300.0" y="212.0">2 to 3×</text>
|
||||
<rect class="nj-charts-c1" x="343.4" y="46.9" width="54.9" height="149.1" rx="3"><title>3 to 5×: 58</title></rect>
|
||||
<text class="nj-charts-val" x="370.9" y="41.9" text-anchor="middle">58</text>
|
||||
<text class="nj-charts-tick" x="370.9" y="212.0">3 to 5×</text>
|
||||
<rect class="nj-charts-c1" x="414.3" y="131.7" width="54.9" height="64.3" rx="3"><title>5 to 10×: 25</title></rect>
|
||||
<text class="nj-charts-val" x="441.7" y="126.7" text-anchor="middle">25</text>
|
||||
<text class="nj-charts-tick" x="441.7" y="212.0">5 to 10×</text>
|
||||
<rect class="nj-charts-c1" x="485.1" y="185.7" width="54.9" height="10.3" rx="3"><title>10× or more: 4</title></rect>
|
||||
<text class="nj-charts-val" x="512.6" y="180.7" text-anchor="middle">4</text>
|
||||
<text class="nj-charts-tick" x="512.6" y="212.0">10× or more</text>
|
||||
<line class="nj-charts-axis" x1="52" y1="196" x2="548" y2="196"/>
|
||||
<text class="nj-charts-tick" x="300" y="240">speedup over 3.12.0, more is better</text>
|
||||
<text class="nj-charts-tick" transform="rotate(-90)" x="-106" y="14">number of benchmarks</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,102 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog" viewBox="0 0 620 482" role="img" aria-labelledby="nj-blog-heldout nj-blog-heldout-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-heldout">Validating 19 files 3.13.0 was not tuned on: json_document's time relative to the fastest other library per file</title>
|
||||
<desc id="nj-blog-heldout-d">Dot plot per file, less is better; below 1.0 json_document is the fastest fully validating library. mesh: Mac 0.68, x86-64 0.44 (serde_json (Rust)); marine_ik: Mac 0.59, x86-64 0.64 (Boost.J​SON); semanticscholar-corpus: Mac 0.79, x86-64 0.65 (sonic-rs (Rust)); gsoc-2018: Mac 0.60, x86-64 0.66 (Boost.J​SON); twitter_api_compact_response: Mac 0.91, x86-64 0.70 (simdjson); twitterescaped: Mac 0.93, x86-64 0.76 (simdjson); numbers: Mac 0.67, x86-64 0.77 (Boost.J​SON); github_events: Mac 0.79, x86-64 0.77 (simdjson); update-center: Mac 0.88, x86-64 0.79 (simdjson); twitter_timeline: Mac 0.97, x86-64 0.80 (yyjson); twitter_api_response: Mac 0.93, x86-64 0.81 (simdjson); google_maps_api_compact_response: Mac 0.86, x86-64 0.81 (yyjson); repeat: Mac 0.65, x86-64 0.82 (simdjson); random: Mac 0.81, x86-64 0.88 (simdjson); apache_builds: Mac 1.08, x86-64 0.90 (simdjson); instruments: Mac 0.90, x86-64 0.92 (simdjson); mesh.pretty: Mac 0.86, x86-64 0.92 (Boost.J​SON); tree-pretty: Mac 0.93, x86-64 0.96 (simdjson); google_maps_api_response: Mac 0.93, x86-64 0.99 (simdjson).</desc>
|
||||
<line class="nj-charts-grid" x1="262" y1="50" x2="262" y2="438"/>
|
||||
<text class="nj-charts-tick" x="262" y="454">0.4×</text>
|
||||
<line class="nj-charts-grid" x1="291.867" y1="50" x2="291.867" y2="438"/>
|
||||
<text class="nj-charts-tick" x="291.867" y="454">0.5×</text>
|
||||
<line class="nj-charts-grid" x1="321.733" y1="50" x2="321.733" y2="438"/>
|
||||
<text class="nj-charts-tick" x="321.733" y="454">0.6×</text>
|
||||
<line class="nj-charts-grid" x1="351.6" y1="50" x2="351.6" y2="438"/>
|
||||
<text class="nj-charts-tick" x="351.6" y="454">0.7×</text>
|
||||
<line class="nj-charts-grid" x1="381.467" y1="50" x2="381.467" y2="438"/>
|
||||
<text class="nj-charts-tick" x="381.467" y="454">0.8×</text>
|
||||
<line class="nj-charts-grid" x1="411.333" y1="50" x2="411.333" y2="438"/>
|
||||
<text class="nj-charts-tick" x="411.333" y="454">0.9×</text>
|
||||
<line class="nj-charts-grid" x1="441.2" y1="50" x2="441.2" y2="438"/>
|
||||
<text class="nj-charts-tick" x="441.2" y="454">1.0×</text>
|
||||
<line class="nj-charts-grid" x1="471.067" y1="50" x2="471.067" y2="438"/>
|
||||
<text class="nj-charts-tick" x="471.067" y="454">1.1×</text>
|
||||
<text class="nj-charts-tick" x="374" y="472">json_document’s time / the fastest other library’s, less is better</text>
|
||||
<circle class="nj-charts-json-dot" cx="13" cy="14" r="5"/><text class="nj-charts-leg" x="23" y="18.5">Apple M1 Max</text>
|
||||
<circle class="nj-charts-ojson-dot" cx="134.2" cy="14" r="5"/><text class="nj-charts-leg" x="144.2" y="18.5">x86-64, G​CC 16.2</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="48">next on x86-64</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="68" text-anchor="end">mesh</text>
|
||||
<circle class="nj-charts-json-dot" cx="344.8" cy="60.5" r="4.5"><title>mesh, Apple M1 Max: 0.68× the time of Glaze</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="273.6" cy="67.5" r="4.5"><title>mesh, x86-64, G​CC 16.2: 0.44× the time of serde_json (Rust)</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="68">serde_json (Rust)</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="88" text-anchor="end">marine_ik</text>
|
||||
<circle class="nj-charts-json-dot" cx="319.5" cy="80.5" r="4.5"><title>marine_ik, Apple M1 Max: 0.59× the time of Glaze</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="334.2" cy="87.5" r="4.5"><title>marine_ik, x86-64, G​CC 16.2: 0.64× the time of Boost.J​SON</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="88">Boost.J​SON</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="108" text-anchor="end">semanticscholar-corpus</text>
|
||||
<circle class="nj-charts-json-dot" cx="377.9" cy="100.5" r="4.5"><title>semanticscholar-corpus, Apple M1 Max: 0.79× the time of sonic-rs (Rust)</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="336.0" cy="107.5" r="4.5"><title>semanticscholar-corpus, x86-64, G​CC 16.2: 0.65× the time of sonic-rs (Rust)</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="108">sonic-rs (Rust)</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="128" text-anchor="end">gsoc-2018</text>
|
||||
<circle class="nj-charts-json-dot" cx="322.9" cy="120.5" r="4.5"><title>gsoc-2018, Apple M1 Max: 0.60× the time of sonic-rs (Rust)</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="338.8" cy="127.5" r="4.5"><title>gsoc-2018, x86-64, G​CC 16.2: 0.66× the time of Boost.J​SON</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="128">Boost.J​SON</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="148" text-anchor="end">twitter_api_compact_response</text>
|
||||
<circle class="nj-charts-json-dot" cx="414.0" cy="140.5" r="4.5"><title>twitter_api_compact_response, Apple M1 Max: 0.91× the time of yyjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="352.1" cy="147.5" r="4.5"><title>twitter_api_compact_response, x86-64, G​CC 16.2: 0.70× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="148">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="168" text-anchor="end">twitterescaped</text>
|
||||
<circle class="nj-charts-json-dot" cx="419.5" cy="160.5" r="4.5"><title>twitterescaped, Apple M1 Max: 0.93× the time of yyjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="370.8" cy="167.5" r="4.5"><title>twitterescaped, x86-64, G​CC 16.2: 0.76× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="168">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="188" text-anchor="end">numbers</text>
|
||||
<circle class="nj-charts-json-dot" cx="343.3" cy="180.5" r="4.5"><title>numbers, Apple M1 Max: 0.67× the time of Boost.J​SON</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="373.1" cy="187.5" r="4.5"><title>numbers, x86-64, G​CC 16.2: 0.77× the time of Boost.J​SON</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="188">Boost.J​SON</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="208" text-anchor="end">github_events</text>
|
||||
<circle class="nj-charts-json-dot" cx="379.5" cy="200.5" r="4.5"><title>github_events, Apple M1 Max: 0.79× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="373.4" cy="207.5" r="4.5"><title>github_events, x86-64, G​CC 16.2: 0.77× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="208">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="228" text-anchor="end">update-center</text>
|
||||
<circle class="nj-charts-json-dot" cx="405.1" cy="220.5" r="4.5"><title>update-center, Apple M1 Max: 0.88× the time of sonic-rs (Rust)</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="377.7" cy="227.5" r="4.5"><title>update-center, x86-64, G​CC 16.2: 0.79× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="228">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="248" text-anchor="end">twitter_timeline</text>
|
||||
<circle class="nj-charts-json-dot" cx="431.6" cy="240.5" r="4.5"><title>twitter_timeline, Apple M1 Max: 0.97× the time of yyjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="381.3" cy="247.5" r="4.5"><title>twitter_timeline, x86-64, G​CC 16.2: 0.80× the time of yyjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="248">yyjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="268" text-anchor="end">twitter_api_response</text>
|
||||
<circle class="nj-charts-json-dot" cx="420.4" cy="260.5" r="4.5"><title>twitter_api_response, Apple M1 Max: 0.93× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="384.1" cy="267.5" r="4.5"><title>twitter_api_response, x86-64, G​CC 16.2: 0.81× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="268">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="288" text-anchor="end">google_maps_api_compact_response</text>
|
||||
<circle class="nj-charts-json-dot" cx="399.2" cy="280.5" r="4.5"><title>google_maps_api_compact_response, Apple M1 Max: 0.86× the time of yyjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="384.2" cy="287.5" r="4.5"><title>google_maps_api_compact_response, x86-64, G​CC 16.2: 0.81× the time of yyjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="288">yyjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="308" text-anchor="end">repeat</text>
|
||||
<circle class="nj-charts-json-dot" cx="336.7" cy="300.5" r="4.5"><title>repeat, Apple M1 Max: 0.65× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="388.2" cy="307.5" r="4.5"><title>repeat, x86-64, G​CC 16.2: 0.82× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="308">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="328" text-anchor="end">random</text>
|
||||
<circle class="nj-charts-json-dot" cx="383.7" cy="320.5" r="4.5"><title>random, Apple M1 Max: 0.81× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="404.9" cy="327.5" r="4.5"><title>random, x86-64, G​CC 16.2: 0.88× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="328">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="348" text-anchor="end">apache_builds</text>
|
||||
<circle class="nj-charts-json-dot" cx="463.6" cy="340.5" r="4.5"><title>apache_builds, Apple M1 Max: 1.08× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="412.4" cy="347.5" r="4.5"><title>apache_builds, x86-64, G​CC 16.2: 0.90× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="348">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="368" text-anchor="end">instruments</text>
|
||||
<circle class="nj-charts-json-dot" cx="412.5" cy="360.5" r="4.5"><title>instruments, Apple M1 Max: 0.90× the time of yyjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="416.2" cy="367.5" r="4.5"><title>instruments, x86-64, G​CC 16.2: 0.92× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="368">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="388" text-anchor="end">mesh.pretty</text>
|
||||
<circle class="nj-charts-json-dot" cx="398.9" cy="380.5" r="4.5"><title>mesh.pretty, Apple M1 Max: 0.86× the time of Glaze</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="418.6" cy="387.5" r="4.5"><title>mesh.pretty, x86-64, G​CC 16.2: 0.92× the time of Boost.J​SON</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="388">Boost.J​SON</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="408" text-anchor="end">tree-pretty</text>
|
||||
<circle class="nj-charts-json-dot" cx="420.1" cy="400.5" r="4.5"><title>tree-pretty, Apple M1 Max: 0.93× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="429.3" cy="407.5" r="4.5"><title>tree-pretty, x86-64, G​CC 16.2: 0.96× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="408">simdjson</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="252" y="428" text-anchor="end">google_maps_api_response</text>
|
||||
<circle class="nj-charts-json-dot" cx="419.0" cy="420.5" r="4.5"><title>google_maps_api_response, Apple M1 Max: 0.93× the time of simdjson</title></circle>
|
||||
<circle class="nj-charts-ojson-dot" cx="439.0" cy="427.5" r="4.5"><title>google_maps_api_response, x86-64, G​CC 16.2: 0.99× the time of simdjson</title></circle>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="500" y="428">simdjson</text>
|
||||
<line class="nj-charts-ref" x1="441.2" y1="50" x2="441.2" y2="438"/>
|
||||
<text class="nj-charts-tick" x="441.2" y="44">as fast as the next</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,72 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--swar" viewBox="0 0 640 294" role="img" aria-labelledby="nj-blog-overlap nj-blog-overlap-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-overlap">Writing an 18-byte string with two overlapping 16-byte loads and stores</title>
|
||||
<desc id="nj-blog-overlap-d">The 18 bytes of profile_link_color. Load a covers bytes 0 to 15, load b covers bytes 2 to 17, so bytes 2 to 15 are in both. Neither contains a byte that needs escaping, so a is stored at the destination and b 2 bytes later; the second store writes bytes 2 to 15 again with the same values. This works for any length from 16 to 32 bytes without a loop.</desc>
|
||||
<text class="fg-h" x="40" y="20">a string of n = 18 bytes: too long for one 16-byte vector, too short for a loop</text>
|
||||
<rect class="fg-cell" x="40" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="53.5" y="58" text-anchor="middle">p</text>
|
||||
<rect class="fg-cell" x="71" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="84.5" y="58" text-anchor="middle">r</text>
|
||||
<rect class="fg-cell" x="102" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="102" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="115.5" y="58" text-anchor="middle">o</text>
|
||||
<rect class="fg-cell" x="133" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="133" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="146.5" y="58" text-anchor="middle">f</text>
|
||||
<rect class="fg-cell" x="164" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="164" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="177.5" y="58" text-anchor="middle">i</text>
|
||||
<rect class="fg-cell" x="195" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="195" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="208.5" y="58" text-anchor="middle">l</text>
|
||||
<rect class="fg-cell" x="226" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="226" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="239.5" y="58" text-anchor="middle">e</text>
|
||||
<rect class="fg-cell" x="257" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="257" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="270.5" y="58" text-anchor="middle">_</text>
|
||||
<rect class="fg-cell" x="288" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="288" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="301.5" y="58" text-anchor="middle">l</text>
|
||||
<rect class="fg-cell" x="319" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="319" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="332.5" y="58" text-anchor="middle">i</text>
|
||||
<rect class="fg-cell" x="350" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="350" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="363.5" y="58" text-anchor="middle">n</text>
|
||||
<rect class="fg-cell" x="381" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="381" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="394.5" y="58" text-anchor="middle">k</text>
|
||||
<rect class="fg-cell" x="412" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="412" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="425.5" y="58" text-anchor="middle">_</text>
|
||||
<rect class="fg-cell" x="443" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="443" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="456.5" y="58" text-anchor="middle">c</text>
|
||||
<rect class="fg-cell" x="474" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="474" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="487.5" y="58" text-anchor="middle">o</text>
|
||||
<rect class="fg-cell" x="505" y="34" width="27" height="36" rx="4"/>
|
||||
<rect class="nj-charts-c3" fill-opacity=".3" x="505" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="518.5" y="58" text-anchor="middle">l</text>
|
||||
<rect class="fg-cell" x="536" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="549.5" y="58" text-anchor="middle">o</text>
|
||||
<rect class="fg-cell" x="567" y="34" width="27" height="36" rx="4"/>
|
||||
<text class="fg-code" x="580.5" y="58" text-anchor="middle">r</text>
|
||||
<text class="nj-charts-tick" x="53.5" y="86">0</text>
|
||||
<text class="nj-charts-tick" x="115.5" y="86">2</text>
|
||||
<text class="nj-charts-tick" x="518.5" y="86">15</text>
|
||||
<text class="nj-charts-tick" x="580.5" y="86">17</text>
|
||||
<rect class="nj-charts-c1" fill-opacity=".22" x="40" y="100" width="492" height="22" rx="4"/>
|
||||
<rect class="nj-charts-c1" x="40" y="100" width="4" height="22" rx="2"/>
|
||||
<rect class="nj-charts-c1" x="528" y="100" width="4" height="22" rx="2"/>
|
||||
<text class="fg-code" x="286" y="116" text-anchor="middle" style="font-size:14px">a = load 16 bytes at p</text>
|
||||
<rect class="nj-charts-c2" fill-opacity=".22" x="102" y="130" width="492" height="22" rx="4"/>
|
||||
<rect class="nj-charts-c2" x="102" y="130" width="4" height="22" rx="2"/>
|
||||
<rect class="nj-charts-c2" x="590" y="130" width="4" height="22" rx="2"/>
|
||||
<text class="fg-code" x="348" y="146" text-anchor="middle" style="font-size:14px">b = load 16 bytes at p + n − 16</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="182">Both loads lie inside the string, and together they cover all of it; bytes 2 to 15 are in both.</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="204">Test a and b for a quote, a backslash, a control character or 0x7F: none, so write</text>
|
||||
<text class="fg-code" x="40" y="234">store a at d, store b at d + n − 16</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="262">The second store writes bytes 2 to 15 again, with the same values. For any n from 16 to 32:</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="280">two loads, one test, two stores, no loop and no branch on the length.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -1,87 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog" viewBox="0 0 560 604" role="img" aria-labelledby="nj-blog-overview nj-blog-overview-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-overview">Speedup of 3.13.0 over 3.12.0 per workload, Apple M1 Max, Apple clang</title>
|
||||
<desc id="nj-blog-overview-d">Horizontal bars of the speedup, more is better. twitter.json 3.1x; citm_catalog.json 4.2x; canada.json 3.4x; canada.json, indented 6.5x; citm, ordered_json 6.8x; twitter, std::ifstream 2.5x; citm, FILE* 4.7x; citm, accept() 7.1x; dump() twitter 6.7x; dump() canada 3.0x; dump(4) citm 4.7x; to_cbor() twitter 4.6x; twitter, memory 3.4x; twitter, FILE* 6.6x; diff() canada 10x; iterate canada 2.7x; copy + destroy citm 1.13x; == citm 1.06x.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="20">Parsing</text>
|
||||
<text class="nj-charts-panel" x="8" y="244">Writing</text>
|
||||
<text class="nj-charts-panel" x="8" y="372">Reading C​BOR</text>
|
||||
<text class="nj-charts-panel" x="8" y="452">Values</text>
|
||||
<line class="nj-charts-grid" x1="220" y1="8" x2="220" y2="560"/>
|
||||
<text class="nj-charts-tick" x="220" y="576">1×</text>
|
||||
<line class="nj-charts-grid" x1="250" y1="8" x2="250" y2="560"/>
|
||||
<text class="nj-charts-tick" x="250" y="576">2×</text>
|
||||
<line class="nj-charts-grid" x1="280" y1="8" x2="280" y2="560"/>
|
||||
<text class="nj-charts-tick" x="280" y="576">3×</text>
|
||||
<line class="nj-charts-grid" x1="310" y1="8" x2="310" y2="560"/>
|
||||
<text class="nj-charts-tick" x="310" y="576">4×</text>
|
||||
<line class="nj-charts-grid" x1="340" y1="8" x2="340" y2="560"/>
|
||||
<text class="nj-charts-tick" x="340" y="576">5×</text>
|
||||
<line class="nj-charts-grid" x1="370" y1="8" x2="370" y2="560"/>
|
||||
<text class="nj-charts-tick" x="370" y="576">6×</text>
|
||||
<line class="nj-charts-grid" x1="400" y1="8" x2="400" y2="560"/>
|
||||
<text class="nj-charts-tick" x="400" y="576">7×</text>
|
||||
<line class="nj-charts-grid" x1="430" y1="8" x2="430" y2="560"/>
|
||||
<text class="nj-charts-tick" x="430" y="576">8×</text>
|
||||
<line class="nj-charts-grid" x1="460" y1="8" x2="460" y2="560"/>
|
||||
<text class="nj-charts-tick" x="460" y="576">9×</text>
|
||||
<line class="nj-charts-grid" x1="490" y1="8" x2="490" y2="560"/>
|
||||
<text class="nj-charts-tick" x="490" y="576">10×</text>
|
||||
<line class="nj-charts-grid" x1="520" y1="8" x2="520" y2="560"/>
|
||||
<text class="nj-charts-tick" x="520" y="576">11×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="42" text-anchor="end">twitter.json</text>
|
||||
<path class="nj-charts-c1" d="M190 30 H280.2 Q284.2 30 284.2 34 V41 Q284.2 45 280.2 45 H190 Z"><title>twitter.json: 3.1×</title></path>
|
||||
<text class="nj-charts-val" x="289.2" y="42">3.1×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="66" text-anchor="end">citm_catalog.json</text>
|
||||
<path class="nj-charts-c1" d="M190 54 H313.5 Q317.5 54 317.5 58 V65 Q317.5 69 313.5 69 H190 Z"><title>citm_catalog.json: 4.2×</title></path>
|
||||
<text class="nj-charts-val" x="322.5" y="66">4.2×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="90" text-anchor="end">canada.json</text>
|
||||
<path class="nj-charts-c1" d="M190 78 H286.5 Q290.5 78 290.5 82 V89 Q290.5 93 286.5 93 H190 Z"><title>canada.json: 3.4×</title></path>
|
||||
<text class="nj-charts-val" x="295.5" y="90">3.4×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="114" text-anchor="end">canada.json, indented</text>
|
||||
<path class="nj-charts-c1" d="M190 102 H381.3 Q385.3 102 385.3 106 V113 Q385.3 117 381.3 117 H190 Z"><title>canada.json, indented: 6.5×</title></path>
|
||||
<text class="nj-charts-val" x="390.3" y="114">6.5×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="138" text-anchor="end">citm, ordered_json</text>
|
||||
<path class="nj-charts-c1" d="M190 126 H391.5 Q395.5 126 395.5 130 V137 Q395.5 141 391.5 141 H190 Z"><title>citm, ordered_json: 6.8×</title></path>
|
||||
<text class="nj-charts-val" x="400.5" y="138">6.8×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="162" text-anchor="end">twitter, std::ifstream</text>
|
||||
<path class="nj-charts-c1" d="M190 150 H261 Q265 150 265 154 V161 Q265 165 261 165 H190 Z"><title>twitter, std::ifstream: 2.5×</title></path>
|
||||
<text class="nj-charts-val" x="270" y="162">2.5×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="186" text-anchor="end">citm, FILE*</text>
|
||||
<path class="nj-charts-c1" d="M190 174 H328.2 Q332.2 174 332.2 178 V185 Q332.2 189 328.2 189 H190 Z"><title>citm, FILE*: 4.7×</title></path>
|
||||
<text class="nj-charts-val" x="337.2" y="186">4.7×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="210" text-anchor="end">citm, accept()</text>
|
||||
<path class="nj-charts-c1" d="M190 198 H398.1 Q402.1 198 402.1 202 V209 Q402.1 213 398.1 213 H190 Z"><title>citm, accept(): 7.1×</title></path>
|
||||
<text class="nj-charts-val" x="407.1" y="210">7.1×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="266" text-anchor="end">dump() twitter</text>
|
||||
<path class="nj-charts-c1" d="M190 254 H387 Q391 254 391 258 V265 Q391 269 387 269 H190 Z"><title>dump() twitter: 6.7×</title></path>
|
||||
<text class="nj-charts-val" x="396" y="266">6.7×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="290" text-anchor="end">dump() canada</text>
|
||||
<path class="nj-charts-c1" d="M190 278 H275.4 Q279.4 278 279.4 282 V289 Q279.4 293 275.4 293 H190 Z"><title>dump() canada: 3.0×</title></path>
|
||||
<text class="nj-charts-val" x="284.4" y="290">3.0×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="314" text-anchor="end">dump(4) citm</text>
|
||||
<path class="nj-charts-c1" d="M190 302 H327 Q331 302 331 306 V313 Q331 317 327 317 H190 Z"><title>dump(4) citm: 4.7×</title></path>
|
||||
<text class="nj-charts-val" x="336" y="314">4.7×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="338" text-anchor="end">to_cbor() twitter</text>
|
||||
<path class="nj-charts-c1" d="M190 326 H323.7 Q327.7 326 327.7 330 V337 Q327.7 341 323.7 341 H190 Z"><title>to_cbor() twitter: 4.6×</title></path>
|
||||
<text class="nj-charts-val" x="332.7" y="338">4.6×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="394" text-anchor="end">twitter, memory</text>
|
||||
<path class="nj-charts-c1" d="M190 382 H287.7 Q291.7 382 291.7 386 V393 Q291.7 397 287.7 397 H190 Z"><title>twitter, memory: 3.4×</title></path>
|
||||
<text class="nj-charts-val" x="296.7" y="394">3.4×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="418" text-anchor="end">twitter, FILE*</text>
|
||||
<path class="nj-charts-c1" d="M190 406 H383.7 Q387.7 406 387.7 410 V417 Q387.7 421 383.7 421 H190 Z"><title>twitter, FILE*: 6.6×</title></path>
|
||||
<text class="nj-charts-val" x="392.7" y="418">6.6×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="474" text-anchor="end">diff() canada</text>
|
||||
<path class="nj-charts-c1" d="M190 462 H499.8 Q503.8 462 503.8 466 V473 Q503.8 477 499.8 477 H190 Z"><title>diff() canada: 10×</title></path>
|
||||
<text class="nj-charts-val" x="508.8" y="474">10×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="498" text-anchor="end">iterate canada</text>
|
||||
<path class="nj-charts-c1" d="M190 486 H267.9 Q271.9 486 271.9 490 V497 Q271.9 501 267.9 501 H190 Z"><title>iterate canada: 2.7×</title></path>
|
||||
<text class="nj-charts-val" x="276.9" y="498">2.7×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="522" text-anchor="end">copy + destroy citm</text>
|
||||
<path class="nj-charts-c1" d="M190 510 H219.9 Q223.9 510 223.9 514 V521 Q223.9 525 219.9 525 H190 Z"><title>copy + destroy citm: 1.13×</title></path>
|
||||
<text class="nj-charts-val" x="228.9" y="522">1.13×</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-tick--r" x="182" y="546" text-anchor="end">== citm</text>
|
||||
<path class="nj-charts-c1" d="M190 534 H217.8 Q221.8 534 221.8 538 V545 Q221.8 549 217.8 549 H190 Z"><title>== citm: 1.06×</title></path>
|
||||
<text class="nj-charts-val" x="226.8" y="546">1.06×</text>
|
||||
<line class="nj-charts-ref" x1="220" y1="8" x2="220" y2="560"/>
|
||||
<line class="nj-charts-zero" x1="190" y1="8" x2="190" y2="560"/>
|
||||
<text class="nj-charts-tick" x="355" y="594">speedup over 3.12.0 (3.12.0 = 1×), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.1 KiB |
@@ -1,99 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog" viewBox="0 0 600 618" role="img" aria-labelledby="nj-blog-price nj-blog-price-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-price">Compile time of two programs with 3.13.0, alone, with a precompiled header and as a module, compared with 3.12.0</title>
|
||||
<desc id="nj-blog-price-d">Horizontal bars of the change in compile time against 3.12.0, less is better. Apple clang 21, -O0 (debug), count_numbers, 3.13.0: +38 %; Apple clang 21, -O0 (debug), count_numbers, 3.13.0, precompiled header: -28 %; Apple clang 21, -O0 (debug), count_numbers, 3.13.0, module: -4 %; Apple clang 21, -O0 (debug), server_config, 3.13.0: +34 %; Apple clang 21, -O0 (debug), server_config, 3.13.0, precompiled header: -23 %; Apple clang 21, -O0 (debug), server_config, 3.13.0, module: +2 %; Apple clang 21, -O2, count_numbers, 3.13.0: +49 %; Apple clang 21, -O2, count_numbers, 3.13.0, precompiled header: +5 %; Apple clang 21, -O2, count_numbers, 3.13.0, module: +21 %; Apple clang 21, -O2, server_config, 3.13.0: +45 %; Apple clang 21, -O2, server_config, 3.13.0, precompiled header: +10 %; Apple clang 21, -O2, server_config, 3.13.0, module: +24 %; G​CC 16, -O0 (debug), count_numbers, 3.13.0: +62 %; G​CC 16, -O0 (debug), count_numbers, 3.13.0, precompiled header: +10 %; G​CC 16, -O0 (debug), count_numbers, 3.13.0, module: +8 %; G​CC 16, -O0 (debug), server_config, 3.13.0: +47 %; G​CC 16, -O0 (debug), server_config, 3.13.0, precompiled header: +14 %; G​CC 16, -O0 (debug), server_config, 3.13.0, module: +15 %; G​CC 16, -O2, count_numbers, 3.13.0: +58 %; G​CC 16, -O2, count_numbers, 3.13.0, precompiled header: +28 %; G​CC 16, -O2, count_numbers, 3.13.0, module: +25 %; G​CC 16, -O2, server_config, 3.13.0: +51 %; G​CC 16, -O2, server_config, 3.13.0, precompiled header: +28 %; G​CC 16, -O2, server_config, 3.13.0, module: +30 %.</desc>
|
||||
<rect class="nj-charts-c2" x="8" y="6" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="26" y="16.5">3.13.0</text>
|
||||
<rect class="nj-charts-c1" x="97.2" y="6" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="115.2" y="16.5">3.13.0, precompiled header</text>
|
||||
<rect class="nj-charts-c3" x="350.4" y="6" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="368.4" y="16.5">3.13.0, module</text>
|
||||
<text class="nj-charts-tick" x="320.833" y="46">as fast as 3.12.0</text>
|
||||
<text class="nj-charts-panel" x="8" y="68">Apple clang 21, -O0 (debug)</text>
|
||||
<line class="nj-charts-grid" x1="184.167" y1="74" x2="184.167" y2="170"/>
|
||||
<line class="nj-charts-grid" x1="252.5" y1="74" x2="252.5" y2="170"/>
|
||||
<line class="nj-charts-grid" x1="389.167" y1="74" x2="389.167" y2="170"/>
|
||||
<line class="nj-charts-grid" x1="457.5" y1="74" x2="457.5" y2="170"/>
|
||||
<line class="nj-charts-grid" x1="525.833" y1="74" x2="525.833" y2="170"/>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="101" text-anchor="end">count_numbers</text>
|
||||
<path class="nj-charts-c2" d="M320.833 78 H446.667 Q450.667 78 450.667 82 V85 Q450.667 89 446.667 89 H320.833 Z"><title>count_numbers, Apple clang 21, -O0 (debug), 3.13.0: 1,320 ms against 955 ms with 3.12.0 (+38 %)</title></path>
|
||||
<text class="nj-charts-val" x="455.667" y="87.5">+38 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 92 H229.167 Q225.167 92 225.167 96 V99 Q225.167 103 229.167 103 H320.833 Z"><title>count_numbers, Apple clang 21, -O0 (debug), 3.13.0, precompiled header: 688 ms against 955 ms with 3.12.0 (−28 %)</title></path>
|
||||
<text class="nj-charts-val" x="220.167" y="101.5" text-anchor="end">−28 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 106 H311.167 Q307.167 106 307.167 110 V113 Q307.167 117 311.167 117 H320.833 Z"><title>count_numbers, Apple clang 21, -O0 (debug), 3.13.0, module: 918 ms against 955 ms with 3.12.0 (−4 %)</title></path>
|
||||
<text class="nj-charts-val" x="302.167" y="115.5" text-anchor="end">−4 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="150" text-anchor="end">server_config</text>
|
||||
<path class="nj-charts-c2" d="M320.833 127 H433 Q437 127 437 131 V134 Q437 138 433 138 H320.833 Z"><title>server_config, Apple clang 21, -O0 (debug), 3.13.0: 1,496 ms against 1,113 ms with 3.12.0 (+34 %)</title></path>
|
||||
<text class="nj-charts-val" x="442" y="136.5">+34 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 141 H246.25 Q242.25 141 242.25 145 V148 Q242.25 152 246.25 152 H320.833 Z"><title>server_config, Apple clang 21, -O0 (debug), 3.13.0, precompiled header: 863 ms against 1,113 ms with 3.12.0 (−23 %)</title></path>
|
||||
<text class="nj-charts-val" x="237.25" y="150.5" text-anchor="end">−23 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 155 H323.667 Q327.667 155 327.667 159 V162 Q327.667 166 323.667 166 H320.833 Z"><title>server_config, Apple clang 21, -O0 (debug), 3.13.0, module: 1,136 ms against 1,113 ms with 3.12.0 (+2 %)</title></path>
|
||||
<text class="nj-charts-val" x="332.667" y="164.5">+2 %</text>
|
||||
<text class="nj-charts-panel" x="8" y="198">Apple clang 21, -O2</text>
|
||||
<line class="nj-charts-grid" x1="184.167" y1="204" x2="184.167" y2="300"/>
|
||||
<line class="nj-charts-grid" x1="252.5" y1="204" x2="252.5" y2="300"/>
|
||||
<line class="nj-charts-grid" x1="389.167" y1="204" x2="389.167" y2="300"/>
|
||||
<line class="nj-charts-grid" x1="457.5" y1="204" x2="457.5" y2="300"/>
|
||||
<line class="nj-charts-grid" x1="525.833" y1="204" x2="525.833" y2="300"/>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="231" text-anchor="end">count_numbers</text>
|
||||
<path class="nj-charts-c2" d="M320.833 208 H484.25 Q488.25 208 488.25 212 V215 Q488.25 219 484.25 219 H320.833 Z"><title>count_numbers, Apple clang 21, -O2, 3.13.0: 2,081 ms against 1,393 ms with 3.12.0 (+49 %)</title></path>
|
||||
<text class="nj-charts-val" x="493.25" y="217.5">+49 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 222 H333.917 Q337.917 222 337.917 226 V229 Q337.917 233 333.917 233 H320.833 Z"><title>count_numbers, Apple clang 21, -O2, 3.13.0, precompiled header: 1,458 ms against 1,393 ms with 3.12.0 (+5 %)</title></path>
|
||||
<text class="nj-charts-val" x="342.917" y="231.5">+5 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 236 H388.583 Q392.583 236 392.583 240 V243 Q392.583 247 388.583 247 H320.833 Z"><title>count_numbers, Apple clang 21, -O2, 3.13.0, module: 1,685 ms against 1,393 ms with 3.12.0 (+21 %)</title></path>
|
||||
<text class="nj-charts-val" x="397.583" y="245.5">+21 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="280" text-anchor="end">server_config</text>
|
||||
<path class="nj-charts-c2" d="M320.833 257 H470.583 Q474.583 257 474.583 261 V264 Q474.583 268 470.583 268 H320.833 Z"><title>server_config, Apple clang 21, -O2, 3.13.0: 2,546 ms against 1,754 ms with 3.12.0 (+45 %)</title></path>
|
||||
<text class="nj-charts-val" x="479.583" y="266.5">+45 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 271 H351 Q355 271 355 275 V278 Q355 282 351 282 H320.833 Z"><title>server_config, Apple clang 21, -O2, 3.13.0, precompiled header: 1,925 ms against 1,754 ms with 3.12.0 (+10 %)</title></path>
|
||||
<text class="nj-charts-val" x="360" y="280.5">+10 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 285 H398.833 Q402.833 285 402.833 289 V292 Q402.833 296 398.833 296 H320.833 Z"><title>server_config, Apple clang 21, -O2, 3.13.0, module: 2,169 ms against 1,754 ms with 3.12.0 (+24 %)</title></path>
|
||||
<text class="nj-charts-val" x="407.833" y="294.5">+24 %</text>
|
||||
<text class="nj-charts-panel" x="8" y="328">G​CC 16, -O0 (debug)</text>
|
||||
<line class="nj-charts-grid" x1="184.167" y1="334" x2="184.167" y2="430"/>
|
||||
<line class="nj-charts-grid" x1="252.5" y1="334" x2="252.5" y2="430"/>
|
||||
<line class="nj-charts-grid" x1="389.167" y1="334" x2="389.167" y2="430"/>
|
||||
<line class="nj-charts-grid" x1="457.5" y1="334" x2="457.5" y2="430"/>
|
||||
<line class="nj-charts-grid" x1="525.833" y1="334" x2="525.833" y2="430"/>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="361" text-anchor="end">count_numbers</text>
|
||||
<path class="nj-charts-c2" d="M320.833 338 H528.667 Q532.667 338 532.667 342 V345 Q532.667 349 528.667 349 H320.833 Z"><title>count_numbers, G​CC 16, -O0 (debug), 3.13.0: 2,548 ms against 1,569 ms with 3.12.0 (+62 %)</title></path>
|
||||
<text class="nj-charts-val" x="537.667" y="347.5">+62 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 352 H351 Q355 352 355 356 V359 Q355 363 351 363 H320.833 Z"><title>count_numbers, G​CC 16, -O0 (debug), 3.13.0, precompiled header: 1,725 ms against 1,569 ms with 3.12.0 (+10 %)</title></path>
|
||||
<text class="nj-charts-val" x="360" y="361.5">+10 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 366 H344.167 Q348.167 366 348.167 370 V373 Q348.167 377 344.167 377 H320.833 Z"><title>count_numbers, G​CC 16, -O0 (debug), 3.13.0, module: 1,700 ms against 1,569 ms with 3.12.0 (+8 %)</title></path>
|
||||
<text class="nj-charts-val" x="353.167" y="375.5">+8 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="410" text-anchor="end">server_config</text>
|
||||
<path class="nj-charts-c2" d="M320.833 387 H477.417 Q481.417 387 481.417 391 V394 Q481.417 398 477.417 398 H320.833 Z"><title>server_config, G​CC 16, -O0 (debug), 3.13.0: 2,985 ms against 2,025 ms with 3.12.0 (+47 %)</title></path>
|
||||
<text class="nj-charts-val" x="486.417" y="396.5">+47 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 401 H364.667 Q368.667 401 368.667 405 V408 Q368.667 412 364.667 412 H320.833 Z"><title>server_config, G​CC 16, -O0 (debug), 3.13.0, precompiled header: 2,302 ms against 2,025 ms with 3.12.0 (+14 %)</title></path>
|
||||
<text class="nj-charts-val" x="373.667" y="410.5">+14 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 415 H368.083 Q372.083 415 372.083 419 V422 Q372.083 426 368.083 426 H320.833 Z"><title>server_config, G​CC 16, -O0 (debug), 3.13.0, module: 2,326 ms against 2,025 ms with 3.12.0 (+15 %)</title></path>
|
||||
<text class="nj-charts-val" x="377.083" y="424.5">+15 %</text>
|
||||
<text class="nj-charts-panel" x="8" y="458">G​CC 16, -O2</text>
|
||||
<line class="nj-charts-grid" x1="184.167" y1="464" x2="184.167" y2="560"/>
|
||||
<line class="nj-charts-grid" x1="252.5" y1="464" x2="252.5" y2="560"/>
|
||||
<line class="nj-charts-grid" x1="389.167" y1="464" x2="389.167" y2="560"/>
|
||||
<line class="nj-charts-grid" x1="457.5" y1="464" x2="457.5" y2="560"/>
|
||||
<line class="nj-charts-grid" x1="525.833" y1="464" x2="525.833" y2="560"/>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="491" text-anchor="end">count_numbers</text>
|
||||
<path class="nj-charts-c2" d="M320.833 468 H515 Q519 468 519 472 V475 Q519 479 515 479 H320.833 Z"><title>count_numbers, G​CC 16, -O2, 3.13.0: 3,702 ms against 2,336 ms with 3.12.0 (+58 %)</title></path>
|
||||
<text class="nj-charts-val" x="524" y="477.5">+58 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 482 H412.5 Q416.5 482 416.5 486 V489 Q416.5 493 412.5 493 H320.833 Z"><title>count_numbers, G​CC 16, -O2, 3.13.0, precompiled header: 2,987 ms against 2,336 ms with 3.12.0 (+28 %)</title></path>
|
||||
<text class="nj-charts-val" x="421.5" y="491.5">+28 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 496 H402.25 Q406.25 496 406.25 500 V503 Q406.25 507 402.25 507 H320.833 Z"><title>count_numbers, G​CC 16, -O2, 3.13.0, module: 2,913 ms against 2,336 ms with 3.12.0 (+25 %)</title></path>
|
||||
<text class="nj-charts-val" x="411.25" y="505.5">+25 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-code" x="142" y="540" text-anchor="end">server_config</text>
|
||||
<path class="nj-charts-c2" d="M320.833 517 H491.083 Q495.083 517 495.083 521 V524 Q495.083 528 491.083 528 H320.833 Z"><title>server_config, G​CC 16, -O2, 3.13.0: 4,714 ms against 3,122 ms with 3.12.0 (+51 %)</title></path>
|
||||
<text class="nj-charts-val" x="500.083" y="526.5">+51 %</text>
|
||||
<path class="nj-charts-c1" d="M320.833 531 H412.5 Q416.5 531 416.5 535 V538 Q416.5 542 412.5 542 H320.833 Z"><title>server_config, G​CC 16, -O2, 3.13.0, precompiled header: 4,006 ms against 3,122 ms with 3.12.0 (+28 %)</title></path>
|
||||
<text class="nj-charts-val" x="421.5" y="540.5">+28 %</text>
|
||||
<path class="nj-charts-c3" d="M320.833 545 H419.333 Q423.333 545 423.333 549 V552 Q423.333 556 419.333 556 H320.833 Z"><title>server_config, G​CC 16, -O2, 3.13.0, module: 4,055 ms against 3,122 ms with 3.12.0 (+30 %)</title></path>
|
||||
<text class="nj-charts-val" x="428.333" y="554.5">+30 %</text>
|
||||
<line class="nj-charts-ref" x1="320.833" y1="52" x2="320.833" y2="574"/>
|
||||
<text class="nj-charts-tick" x="184.167" y="590">−40 %</text>
|
||||
<text class="nj-charts-tick" x="252.5" y="590">−20 %</text>
|
||||
<text class="nj-charts-tick" x="320.833" y="590">0</text>
|
||||
<text class="nj-charts-tick" x="389.167" y="590">+20 %</text>
|
||||
<text class="nj-charts-tick" x="457.5" y="590">+40 %</text>
|
||||
<text class="nj-charts-tick" x="525.833" y="590">+60 %</text>
|
||||
<text class="nj-charts-tick" x="355" y="608">compile time compared with 3.12.0, less is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,60 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--swar" viewBox="0 0 640 312" role="img" aria-labelledby="nj-blog-swar nj-blog-swar-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-swar">Finding the end of a run of ordinary string characters eight bytes at a time</title>
|
||||
<desc id="nj-blog-swar-d">The eight bytes w, i, t, t, e, r, quote and comma are loaded as one word. The test sets the high bit only in byte 6, the quote. Counting trailing zero bits gives 55, divided by eight gives 6: bytes 0 to 5 are copied at once, then the quote ends the string.</desc>
|
||||
<text class="fg-h" x="40" y="20">eight input bytes, loaded as one 64-bit word (byte 0 is the lowest)</text>
|
||||
<rect class="fg-cell" x="40" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="72" y="60" text-anchor="middle">w</text>
|
||||
<text class="nj-charts-tick" x="72" y="92">0x77</text>
|
||||
<text class="nj-charts-tick" x="72" y="108">byte 0</text>
|
||||
<rect class="fg-cell" x="110" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="142" y="60" text-anchor="middle">i</text>
|
||||
<text class="nj-charts-tick" x="142" y="92">0x69</text>
|
||||
<text class="nj-charts-tick" x="142" y="108">byte 1</text>
|
||||
<rect class="fg-cell" x="180" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="212" y="60" text-anchor="middle">t</text>
|
||||
<text class="nj-charts-tick" x="212" y="92">0x74</text>
|
||||
<text class="nj-charts-tick" x="212" y="108">byte 2</text>
|
||||
<rect class="fg-cell" x="250" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="282" y="60" text-anchor="middle">t</text>
|
||||
<text class="nj-charts-tick" x="282" y="92">0x74</text>
|
||||
<text class="nj-charts-tick" x="282" y="108">byte 3</text>
|
||||
<rect class="fg-cell" x="320" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="352" y="60" text-anchor="middle">e</text>
|
||||
<text class="nj-charts-tick" x="352" y="92">0x65</text>
|
||||
<text class="nj-charts-tick" x="352" y="108">byte 4</text>
|
||||
<rect class="fg-cell" x="390" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="422" y="60" text-anchor="middle">r</text>
|
||||
<text class="nj-charts-tick" x="422" y="92">0x72</text>
|
||||
<text class="nj-charts-tick" x="422" y="108">byte 5</text>
|
||||
<rect class="fg-cell" x="460" y="34" width="64" height="40" rx="4"/>
|
||||
<rect class="nj-charts-c2" fill-opacity=".25" x="460" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="492" y="60" text-anchor="middle">"</text>
|
||||
<text class="nj-charts-tick" x="492" y="92">0x22</text>
|
||||
<text class="nj-charts-tick" x="492" y="108">byte 6</text>
|
||||
<rect class="fg-cell" x="530" y="34" width="64" height="40" rx="4"/>
|
||||
<text class="fg-code" x="562" y="60" text-anchor="middle">,</text>
|
||||
<text class="nj-charts-tick" x="562" y="92">0x2C</text>
|
||||
<text class="nj-charts-tick" x="562" y="108">byte 7</text>
|
||||
<text class="fg-h" x="40" y="132">swar_string_special(): the high bit of each byte that needs handling</text>
|
||||
<rect class="fg-cell" x="40" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="72" y="169" text-anchor="middle">0x00</text>
|
||||
<rect class="fg-cell" x="110" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="142" y="169" text-anchor="middle">0x00</text>
|
||||
<rect class="fg-cell" x="180" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="212" y="169" text-anchor="middle">0x00</text>
|
||||
<rect class="fg-cell" x="250" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="282" y="169" text-anchor="middle">0x00</text>
|
||||
<rect class="fg-cell" x="320" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="352" y="169" text-anchor="middle">0x00</text>
|
||||
<rect class="fg-cell" x="390" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="422" y="169" text-anchor="middle">0x00</text>
|
||||
<rect class="fg-cell" x="460" y="146" width="64" height="34" rx="4"/>
|
||||
<rect class="nj-charts-c2" fill-opacity=".25" x="460" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="492" y="169" text-anchor="middle">0x80</text>
|
||||
<rect class="fg-cell" x="530" y="146" width="64" height="34" rx="4"/>
|
||||
<text class="fg-code" x="562" y="169" text-anchor="middle">0x00</text>
|
||||
<text class="fg-code" x="40" y="216">count_trailing_zeros(0x0080000000000000) = 55</text>
|
||||
<text class="fg-code" x="40" y="242">55 / 8 = 6: copy bytes 0 to 5 in one go, then handle the quote</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="272">No branch per byte: a few subtractions, ANDs and ORs per word,</text>
|
||||
<text class="fg-note fg-note--l" x="40" y="290">then one count of trailing zeros.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.4 KiB |
@@ -1,45 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-accept_twitter nj-blog-tl-accept_twitter-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-accept_twitter">accept() twitter.json: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-accept_twitter-d">accept() twitter.json: speedup over 3.12.0 at each of 353 commits, ending at 5.1x. Labeled steps, by theme: 4, 1, 4, 4, 2, 2.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">accept() twitter.json</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="160.667" x2="330" y2="160.667"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="164.667">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="113.333" x2="330" y2="113.333"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="117.333">4×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">8×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,208.1 45.6,208.1 45.6,207.8 46.4,207.8 46.4,208.0 47.2,208.0 47.2,207.7 48.1,207.7 48.1,207.9 48.9,207.9 48.9,208.0 49.7,208.0 49.7,208.1 50.5,208.1 50.5,208.4 51.3,208.4 51.3,207.1 52.1,207.1 52.1,207.9 52.9,207.9 52.9,208.2 53.8,208.2 53.8,207.9 54.6,207.9 54.6,207.9 55.4,207.9 55.4,207.7 56.2,207.7 56.2,207.9 57.0,207.9 57.0,207.8 57.8,207.8 57.8,207.7 58.6,207.7 58.6,208.2 59.4,208.2 59.4,207.3 60.2,207.3 60.2,208.0 61.1,208.0 61.1,208.0 61.9,208.0 61.9,207.8 62.7,207.8 62.7,207.9 63.5,207.9 63.5,207.9 64.3,207.9 64.3,207.2 65.1,207.2 65.1,207.8 65.9,207.8 65.9,207.6 66.8,207.6 66.8,207.8 67.6,207.8 67.6,207.9 68.4,207.9 68.4,207.9 69.2,207.9 69.2,207.4 70.0,207.4 70.0,207.7 70.8,207.7 70.8,207.6 71.6,207.6 71.6,207.7 72.4,207.7 72.4,208.1 73.2,208.1 73.2,207.8 74.1,207.8 74.1,207.1 74.9,207.1 74.9,207.9 75.7,207.9 75.7,207.1 76.5,207.1 76.5,207.8 77.3,207.8 77.3,207.3 78.1,207.3 78.1,208.1 78.9,208.1 78.9,207.6 79.8,207.6 79.8,207.6 80.6,207.6 80.6,208.1 81.4,208.1 81.4,208.3 82.2,208.3 82.2,207.8 83.0,207.8 83.0,207.7 83.8,207.7 83.8,207.9 84.6,207.9 84.6,207.8 85.4,207.8 85.4,207.5 86.2,207.5 86.2,207.9 87.1,207.9 87.1,207.8 87.9,207.8 87.9,208.0 88.7,208.0 88.7,194.6 89.5,194.6 89.5,195.3 90.3,195.3 90.3,195.6 91.1,195.6 91.1,195.1 91.9,195.1 91.9,195.6 92.8,195.6 92.8,194.6 93.6,194.6 93.6,194.7 94.4,194.7 94.4,195.3 95.2,195.3 95.2,195.1 96.0,195.1 96.0,195.1 96.8,195.1 96.8,195.6 97.6,195.6 97.6,194.6 98.4,194.6 98.4,195.2 99.2,195.2 99.2,195.3 100.1,195.3 100.1,195.6 100.9,195.6 100.9,195.3 101.7,195.3 101.7,195.4 102.5,195.4 102.5,195.2 103.3,195.2 103.3,195.8 104.1,195.8 104.1,195.1 104.9,195.1 104.9,195.3 105.8,195.3 105.8,196.2 106.6,196.2 106.6,195.7 107.4,195.7 107.4,194.5 108.2,194.5 108.2,194.7 109.0,194.7 109.0,195.1 109.8,195.1 109.8,195.6 110.6,195.6 110.6,195.6 111.4,195.6 111.4,195.5 112.2,195.5 112.2,194.6 113.1,194.6 113.1,194.4 113.9,194.4 113.9,195.1 114.7,195.1 114.7,195.4 115.5,195.4 115.5,195.8 116.3,195.8 116.3,194.6 117.1,194.6 117.1,195.0 117.9,195.0 117.9,195.4 118.8,195.4 118.8,195.1 119.6,195.1 119.6,195.5 120.4,195.5 120.4,193.5 121.2,193.5 121.2,194.9 122.0,194.9 122.0,195.1 122.8,195.1 122.8,194.8 123.6,194.8 123.6,194.6 124.4,194.6 124.4,194.7 125.3,194.7 125.3,195.1 126.1,195.1 126.1,195.0 126.9,195.0 126.9,194.7 127.7,194.7 127.7,195.3 128.5,195.3 128.5,194.6 129.3,194.6 129.3,194.7 130.1,194.7 130.1,143.3 130.9,143.3 130.9,143.0 131.8,143.0 131.8,142.2 132.6,142.2 132.6,141.9 133.4,141.9 133.4,143.0 134.2,143.0 134.2,142.6 135.0,142.6 135.0,142.4 135.8,142.4 135.8,142.9 136.6,142.9 136.6,143.1 137.4,143.1 137.4,143.2 138.2,143.2 138.2,142.1 139.1,142.1 139.1,143.1 139.9,143.1 139.9,142.4 140.7,142.4 140.7,143.0 141.5,143.0 141.5,141.8 142.3,141.8 142.3,143.1 143.1,143.1 143.1,141.9 143.9,141.9 143.9,143.1 144.8,143.1 144.8,142.9 145.6,142.9 145.6,142.0 146.4,142.0 146.4,142.5 147.2,142.5 147.2,142.4 148.0,142.4 148.0,143.5 148.8,143.5 148.8,142.9 149.6,142.9 149.6,142.3 150.4,142.3 150.4,143.1 151.2,143.1 151.2,141.9 152.1,141.9 152.1,142.4 152.9,142.4 152.9,141.9 153.7,141.9 153.7,141.8 154.5,141.8 154.5,141.3 155.3,141.3 155.3,142.9 156.1,142.9 156.1,141.2 156.9,141.2 156.9,142.8 157.8,142.8 157.8,142.6 158.6,142.6 158.6,142.3 159.4,142.3 159.4,142.7 160.2,142.7 160.2,142.0 161.0,142.0 161.0,141.5 161.8,141.5 161.8,141.2 162.6,141.2 162.6,141.4 163.4,141.4 163.4,141.9 164.2,141.9 164.2,141.6 165.1,141.6 165.1,141.8 165.9,141.8 165.9,142.0 166.7,142.0 166.7,142.0 167.5,142.0 167.5,141.5 168.3,141.5 168.3,142.4 169.1,142.4 169.1,141.7 169.9,141.7 169.9,142.4 170.8,142.4 170.8,141.9 171.6,141.9 171.6,141.7 172.4,141.7 172.4,141.1 173.2,141.1 173.2,141.5 174.0,141.5 174.0,141.6 174.8,141.6 174.8,141.7 175.6,141.7 175.6,140.3 176.4,140.3 176.4,140.7 177.2,140.7 177.2,140.6 178.1,140.6 178.1,141.0 178.9,141.0 178.9,141.8 179.7,141.8 179.7,141.6 180.5,141.6 180.5,141.5 181.3,141.5 181.3,141.0 182.1,141.0 182.1,141.1 182.9,141.1 182.9,140.7 183.8,140.7 183.8,140.4 184.6,140.4 184.6,142.1 185.4,142.1 185.4,141.7 186.2,141.7 186.2,141.2 187.0,141.2 187.0,141.5 187.8,141.5 187.8,140.4 188.6,140.4 188.6,141.0 189.4,141.0 189.4,141.5 190.2,141.5 190.2,141.2 191.1,141.2 191.1,142.1 191.9,142.1 191.9,140.4 192.7,140.4 192.7,141.1 193.5,141.1 193.5,141.5 194.3,141.5 194.3,140.9 195.1,140.9 195.1,141.7 195.9,141.7 195.9,140.4 196.8,140.4 196.8,141.9 197.6,141.9 197.6,141.1 198.4,141.1 198.4,141.4 199.2,141.4 199.2,140.6 200.0,140.6 200.0,141.4 200.8,141.4 200.8,140.1 201.6,140.1 201.6,141.2 202.4,141.2 202.4,140.8 203.2,140.8 203.2,141.4 204.1,141.4 204.1,141.5 204.9,141.5 204.9,141.2 205.7,141.2 205.7,142.0 206.5,142.0 206.5,142.6 207.3,142.6 207.3,142.3 208.1,142.3 208.1,140.6 208.9,140.6 208.9,140.8 209.8,140.8 209.8,140.9 210.6,140.9 210.6,141.1 211.4,141.1 211.4,141.6 212.2,141.6 212.2,141.0 213.0,141.0 213.0,141.5 213.8,141.5 213.8,141.4 214.6,141.4 214.6,142.0 215.4,142.0 215.4,140.6 216.2,140.6 216.2,1Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="88.7" cy="194.6" r="3.5"><title>#5234: 1.22×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="88.7" y1="54.0" x2="88.7" y2="189.6"/>
|
||||
<circle class="nj-theme-dot" cx="88.7" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="88.7" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="130.1" cy="143.3" r="3.5"><title>#5283: 2.6×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="130.1" y1="54.0" x2="130.1" y2="138.3"/>
|
||||
<circle class="nj-theme-dot" cx="130.1" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="130.1" y="50.0" text-anchor="middle">1</text>
|
||||
<circle class="nj-charts-json-dot" cx="222.8" cy="135.2" r="3.5"><title>#5592: 2.9×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="222.8" y1="54.0" x2="222.8" y2="130.2"/>
|
||||
<circle class="nj-theme-dot" cx="222.8" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="222.8" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="243.1" cy="118.7" r="3.5"><title>#5809: 3.7×</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="243.9" cy="112.7" r="3.5"><title>#5810: 4.0×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="243.9" y1="36.0" x2="243.9" y2="107.7"/>
|
||||
<circle class="nj-theme-dot" cx="234.9" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="234.9" y="32.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-theme-dot" cx="252.9" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="252.9" y="32.0" text-anchor="middle">2</text>
|
||||
<circle class="nj-charts-json-dot" cx="273.1" cy="99.2" r="3.5"><title>#5853: 4.9×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="273.1" y1="54.0" x2="273.1" y2="94.2"/>
|
||||
<circle class="nj-theme-dot" cx="273.1" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="273.1" y="50.0" text-anchor="middle">2</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-dump_canada nj-blog-tl-dump_canada-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-dump_canada">dump() canada.json: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-dump_canada-d">dump() canada.json: speedup over 3.12.0 at each of 353 commits, ending at 3.3x. Labeled steps, by theme: 6, 3.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">dump() canada.json</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="160.667" x2="330" y2="160.667"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="164.667">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="113.333" x2="330" y2="113.333"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="117.333">4×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">8×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,208.0 45.6,208.0 45.6,207.2 46.4,207.2 46.4,207.9 47.2,207.9 47.2,206.7 48.1,206.7 48.1,207.5 48.9,207.5 48.9,207.7 49.7,207.7 49.7,207.3 50.5,207.3 50.5,207.9 51.3,207.9 51.3,206.6 52.1,206.6 52.1,207.5 52.9,207.5 52.9,208.0 53.8,208.0 53.8,207.6 54.6,207.6 54.6,207.2 55.4,207.2 55.4,207.5 56.2,207.5 56.2,206.6 57.0,206.6 57.0,207.1 57.8,207.1 57.8,207.1 58.6,207.1 58.6,207.2 59.4,207.2 59.4,206.6 60.2,206.6 60.2,207.5 61.1,207.5 61.1,207.6 61.9,207.6 61.9,207.7 62.7,207.7 62.7,207.2 63.5,207.2 63.5,206.5 64.3,206.5 64.3,206.8 65.1,206.8 65.1,207.1 65.9,207.1 65.9,207.0 66.8,207.0 66.8,207.1 67.6,207.1 67.6,206.7 68.4,206.7 68.4,208.2 69.2,208.2 69.2,207.5 70.0,207.5 70.0,206.6 70.8,206.6 70.8,206.7 71.6,206.7 71.6,206.3 72.4,206.3 72.4,208.4 73.2,208.4 73.2,207.3 74.1,207.3 74.1,206.8 74.9,206.8 74.9,208.0 75.7,208.0 75.7,207.8 76.5,207.8 76.5,207.1 77.3,207.1 77.3,207.5 78.1,207.5 78.1,207.9 78.9,207.9 78.9,206.3 79.8,206.3 79.8,206.8 80.6,206.8 80.6,207.5 81.4,207.5 81.4,208.1 82.2,208.1 82.2,206.6 83.0,206.6 83.0,207.2 83.8,207.2 83.8,207.2 84.6,207.2 84.6,207.4 85.4,207.4 85.4,207.0 86.2,207.0 86.2,206.7 87.1,206.7 87.1,206.5 87.9,206.5 87.9,207.6 88.7,207.6 88.7,207.4 89.5,207.4 89.5,207.2 90.3,207.2 90.3,207.5 91.1,207.5 91.1,207.6 91.9,207.6 91.9,208.0 92.8,208.0 92.8,208.2 93.6,208.2 93.6,206.7 94.4,206.7 94.4,207.4 95.2,207.4 95.2,206.7 96.0,206.7 96.0,206.6 96.8,206.6 96.8,208.0 97.6,208.0 97.6,208.0 98.4,208.0 98.4,206.3 99.2,206.3 99.2,208.3 100.1,208.3 100.1,207.8 100.9,207.8 100.9,207.4 101.7,207.4 101.7,206.3 102.5,206.3 102.5,208.1 103.3,208.1 103.3,207.5 104.1,207.5 104.1,207.4 104.9,207.4 104.9,207.5 105.8,207.5 105.8,207.7 106.6,207.7 106.6,208.0 107.4,208.0 107.4,207.0 108.2,207.0 108.2,207.5 109.0,207.5 109.0,207.2 109.8,207.2 109.8,207.7 110.6,207.7 110.6,207.3 111.4,207.3 111.4,208.0 112.2,208.0 112.2,206.7 113.1,206.7 113.1,206.6 113.9,206.6 113.9,207.2 114.7,207.2 114.7,208.1 115.5,208.1 115.5,208.1 116.3,208.1 116.3,206.7 117.1,206.7 117.1,207.8 117.9,207.8 117.9,207.6 118.8,207.6 118.8,207.4 119.6,207.4 119.6,207.1 120.4,207.1 120.4,207.5 121.2,207.5 121.2,208.8 122.0,208.8 122.0,209.2 122.8,209.2 122.8,208.4 123.6,208.4 123.6,208.3 124.4,208.3 124.4,208.0 125.3,208.0 125.3,209.0 126.1,209.0 126.1,208.5 126.9,208.5 126.9,209.1 127.7,209.1 127.7,209.2 128.5,209.2 128.5,208.6 129.3,208.6 129.3,207.7 130.1,207.7 130.1,207.7 130.9,207.7 130.9,207.5 131.8,207.5 131.8,202.2 132.6,202.2 132.6,202.3 133.4,202.3 133.4,201.7 134.2,201.7 134.2,202.3 135.0,202.3 135.0,201.9 135.8,201.9 135.8,201.2 136.6,201.2 136.6,202.1 137.4,202.1 137.4,202.6 138.2,202.6 138.2,201.5 139.1,201.5 139.1,202.3 139.9,202.3 139.9,202.3 140.7,202.3 140.7,201.7 141.5,201.7 141.5,201.3 142.3,201.3 142.3,202.5 143.1,202.5 143.1,201.1 143.9,201.1 143.9,202.9 144.8,202.9 144.8,202.2 145.6,202.2 145.6,201.7 146.4,201.7 146.4,201.7 147.2,201.7 147.2,201.6 148.0,201.6 148.0,203.0 148.8,203.0 148.8,202.7 149.6,202.7 149.6,202.4 150.4,202.4 150.4,202.8 151.2,202.8 151.2,202.1 152.1,202.1 152.1,203.1 152.9,203.1 152.9,202.3 153.7,202.3 153.7,202.3 154.5,202.3 154.5,201.8 155.3,201.8 155.3,203.1 156.1,203.1 156.1,201.8 156.9,201.8 156.9,202.6 157.8,202.6 157.8,202.6 158.6,202.6 158.6,202.9 159.4,202.9 159.4,202.3 160.2,202.3 160.2,202.3 161.0,202.3 161.0,201.6 161.8,201.6 161.8,201.5 162.6,201.5 162.6,202.4 163.4,202.4 163.4,201.7 164.2,201.7 164.2,201.2 165.1,201.2 165.1,202.2 165.9,202.2 165.9,201.6 166.7,201.6 166.7,201.6 167.5,201.6 167.5,201.8 168.3,201.8 168.3,202.1 169.1,202.1 169.1,201.7 169.9,201.7 169.9,201.4 170.8,201.4 170.8,202.2 171.6,202.2 171.6,202.7 172.4,202.7 172.4,202.4 173.2,202.4 173.2,201.7 174.0,201.7 174.0,201.7 174.8,201.7 174.8,202.3 175.6,202.3 175.6,201.6 176.4,201.6 176.4,201.7 177.2,201.7 177.2,202.2 178.1,202.2 178.1,202.2 178.9,202.2 178.9,202.4 179.7,202.4 179.7,201.7 180.5,201.7 180.5,202.1 181.3,202.1 181.3,201.6 182.1,201.6 182.1,202.2 182.9,202.2 182.9,201.9 183.8,201.9 183.8,201.9 184.6,201.9 184.6,202.5 185.4,202.5 185.4,201.6 186.2,201.6 186.2,202.1 187.0,202.1 187.0,202.3 187.8,202.3 187.8,201.8 188.6,201.8 188.6,201.5 189.4,201.5 189.4,202.3 190.2,202.3 190.2,202.2 191.1,202.2 191.1,202.9 191.9,202.9 191.9,201.3 192.7,201.3 192.7,202.2 193.5,202.2 193.5,203.6 194.3,203.6 194.3,201.9 195.1,201.9 195.1,202.4 195.9,202.4 195.9,201.7 196.8,201.7 196.8,202.7 197.6,202.7 197.6,202.3 198.4,202.3 198.4,202.5 199.2,202.5 199.2,202.1 200.0,202.1 200.0,203.4 200.8,203.4 200.8,202.1 201.6,202.1 201.6,202.3 202.4,202.3 202.4,201.9 203.2,201.9 203.2,202.3 204.1,202.3 204.1,201.7 204.9,201.7 204.9,202.4 205.7,202.4 205.7,202.3 206.5,202.3 206.5,202.9 207.3,202.9 207.3,202.9 208.1,202.9 208.1,202.2 208.9,202.2 208.9,202.4 209.8,202.4 209.8,202.2 210.6,202.2 210.6,202.7 211.4,202.7 211.4,202.5 212.2,202.5 212.2,202.5 213.0,202.5 213.0,201.5 213.8,201.5 213.8,203.1 214.6,203.1 214.6,203.2 215.4,203.2 215.4,201.5 216.2,201.5 216.2,2Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="131.8" cy="202.2" r="3.5"><title>#5285: 1.09×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="131.8" y1="54.0" x2="131.8" y2="197.2"/>
|
||||
<circle class="nj-theme-dot" cx="131.8" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="131.8" y="50.0" text-anchor="middle">6</text>
|
||||
<circle class="nj-charts-json-dot" cx="246.3" cy="130.7" r="3.5"><title>#5634: 3.1×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="246.3" y1="54.0" x2="246.3" y2="125.7"/>
|
||||
<circle class="nj-theme-dot" cx="246.3" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="246.3" y="50.0" text-anchor="middle">3</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 10 KiB |
@@ -1,37 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-dump_twitter nj-blog-tl-dump_twitter-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-dump_twitter">dump() twitter.json: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-dump_twitter-d">dump() twitter.json: speedup over 3.12.0 at each of 353 commits, ending at 6.8x. Labeled steps, by theme: 6, 2, 2, 2.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">dump() twitter.json</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="172.5" x2="330" y2="172.5"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="176.5">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="137" x2="330" y2="137"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="141">4×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="101.5" x2="330" y2="101.5"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="105.5">8×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">16×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,208.0 45.6,208.0 45.6,207.2 46.4,207.2 46.4,207.9 47.2,207.9 47.2,206.8 48.1,206.8 48.1,208.0 48.9,208.0 48.9,207.4 49.7,207.4 49.7,207.3 50.5,207.3 50.5,208.0 51.3,208.0 51.3,206.8 52.1,206.8 52.1,207.2 52.9,207.2 52.9,208.0 53.8,208.0 53.8,207.2 54.6,207.2 54.6,207.5 55.4,207.5 55.4,206.8 56.2,206.8 56.2,206.9 57.0,206.9 57.0,207.5 57.8,207.5 57.8,207.3 58.6,207.3 58.6,207.8 59.4,207.8 59.4,206.8 60.2,206.8 60.2,207.8 61.1,207.8 61.1,207.4 61.9,207.4 61.9,208.0 62.7,208.0 62.7,207.4 63.5,207.4 63.5,207.3 64.3,207.3 64.3,206.9 65.1,206.9 65.1,207.3 65.9,207.3 65.9,207.4 66.8,207.4 66.8,207.6 67.6,207.6 67.6,207.5 68.4,207.5 68.4,207.6 69.2,207.6 69.2,207.4 70.0,207.4 70.0,207.2 70.8,207.2 70.8,207.1 71.6,207.1 71.6,207.3 72.4,207.3 72.4,207.7 73.2,207.7 73.2,207.8 74.1,207.8 74.1,206.9 74.9,206.9 74.9,207.6 75.7,207.6 75.7,207.0 76.5,207.0 76.5,207.0 77.3,207.0 77.3,207.3 78.1,207.3 78.1,207.6 78.9,207.6 78.9,206.8 79.8,206.8 79.8,207.7 80.6,207.7 80.6,207.4 81.4,207.4 81.4,207.5 82.2,207.5 82.2,207.1 83.0,207.1 83.0,207.3 83.8,207.3 83.8,207.5 84.6,207.5 84.6,207.3 85.4,207.3 85.4,207.3 86.2,207.3 86.2,206.9 87.1,206.9 87.1,207.4 87.9,207.4 87.9,207.9 88.7,207.9 88.7,207.3 89.5,207.3 89.5,206.8 90.3,206.8 90.3,207.6 91.1,207.6 91.1,207.7 91.9,207.7 91.9,208.6 92.8,208.6 92.8,208.5 93.6,208.5 93.6,208.6 94.4,208.6 94.4,209.2 95.2,209.2 95.2,208.5 96.0,208.5 96.0,208.2 96.8,208.2 96.8,209.3 97.6,209.3 97.6,208.4 98.4,208.4 98.4,208.4 99.2,208.4 99.2,209.0 100.1,209.0 100.1,209.0 100.9,209.0 100.9,208.7 101.7,208.7 101.7,208.9 102.5,208.9 102.5,208.7 103.3,208.7 103.3,209.0 104.1,209.0 104.1,208.8 104.9,208.8 104.9,208.7 105.8,208.7 105.8,209.3 106.6,209.3 106.6,208.6 107.4,208.6 107.4,208.5 108.2,208.5 108.2,208.4 109.0,208.4 109.0,208.0 109.8,208.0 109.8,208.9 110.6,208.9 110.6,208.6 111.4,208.6 111.4,208.9 112.2,208.9 112.2,208.1 113.1,208.1 113.1,208.0 113.9,208.0 113.9,208.6 114.7,208.6 114.7,208.5 115.5,208.5 115.5,209.1 116.3,209.1 116.3,208.0 117.1,208.0 117.1,209.1 117.9,209.1 117.9,208.9 118.8,208.9 118.8,208.5 119.6,208.5 119.6,209.1 120.4,209.1 120.4,209.0 121.2,209.0 121.2,208.8 122.0,208.8 122.0,208.6 122.8,208.6 122.8,208.6 123.6,208.6 123.6,208.2 124.4,208.2 124.4,209.0 125.3,209.0 125.3,209.2 126.1,209.2 126.1,209.1 126.9,209.1 126.9,209.2 127.7,209.2 127.7,209.2 128.5,209.2 128.5,208.5 129.3,208.5 129.3,208.7 130.1,208.7 130.1,209.5 130.9,209.5 130.9,208.4 131.8,208.4 131.8,147.4 132.6,147.4 132.6,148.3 133.4,148.3 133.4,148.4 134.2,148.4 134.2,147.5 135.0,147.5 135.0,147.5 135.8,147.5 135.8,147.7 136.6,147.7 136.6,148.2 137.4,148.2 137.4,148.2 138.2,148.2 138.2,147.3 139.1,147.3 139.1,148.1 139.9,148.1 139.9,147.2 140.7,147.2 140.7,147.5 141.5,147.5 141.5,147.3 142.3,147.3 142.3,148.4 143.1,148.4 143.1,147.4 143.9,147.4 143.9,148.3 144.8,148.3 144.8,148.5 145.6,148.5 145.6,147.7 146.4,147.7 146.4,147.8 147.2,147.8 147.2,148.0 148.0,148.0 148.0,148.5 148.8,148.5 148.8,148.0 149.6,148.0 149.6,148.1 150.4,148.1 150.4,148.2 151.2,148.2 151.2,148.3 152.1,148.3 152.1,149.0 152.9,149.0 152.9,148.7 153.7,148.7 153.7,148.2 154.5,148.2 154.5,148.1 155.3,148.1 155.3,148.9 156.1,148.9 156.1,147.7 156.9,147.7 156.9,149.2 157.8,149.2 157.8,149.1 158.6,149.1 158.6,148.8 159.4,148.8 159.4,148.1 160.2,148.1 160.2,148.7 161.0,148.7 161.0,147.7 161.8,147.7 161.8,147.9 162.6,147.9 162.6,147.7 163.4,147.7 163.4,148.3 164.2,148.3 164.2,148.0 165.1,148.0 165.1,148.2 165.9,148.2 165.9,148.4 166.7,148.4 166.7,148.3 167.5,148.3 167.5,148.1 168.3,148.1 168.3,149.0 169.1,149.0 169.1,147.8 169.9,147.8 169.9,148.8 170.8,148.8 170.8,148.3 171.6,148.3 171.6,148.0 172.4,148.0 172.4,147.8 173.2,147.8 173.2,148.0 174.0,148.0 174.0,147.7 174.8,147.7 174.8,148.2 175.6,148.2 175.6,147.1 176.4,147.1 176.4,147.9 177.2,147.9 177.2,147.9 178.1,147.9 178.1,147.9 178.9,147.9 178.9,147.7 179.7,147.7 179.7,148.0 180.5,148.0 180.5,147.4 181.3,147.4 181.3,147.5 182.1,147.5 182.1,147.5 182.9,147.5 182.9,147.0 183.8,147.0 183.8,147.0 184.6,147.0 184.6,148.2 185.4,148.2 185.4,147.7 186.2,147.7 186.2,148.0 187.0,148.0 187.0,148.2 187.8,148.2 187.8,147.7 188.6,147.7 188.6,147.8 189.4,147.8 189.4,148.2 190.2,148.2 190.2,148.3 191.1,148.3 191.1,148.5 191.9,148.5 191.9,148.1 192.7,148.1 192.7,147.9 193.5,147.9 193.5,148.2 194.3,148.2 194.3,147.5 195.1,147.5 195.1,148.1 195.9,148.1 195.9,147.6 196.8,147.6 196.8,148.4 197.6,148.4 197.6,148.2 198.4,148.2 198.4,148.3 199.2,148.3 199.2,148.7 200.0,148.7 200.0,149.4 200.8,149.4 200.8,148.7 201.6,148.7 201.6,149.5 202.4,149.5 202.4,148.2 203.2,148.2 203.2,148.5 204.1,148.5 204.1,149.1 204.9,149.1 204.9,148.8 205.7,148.8 205.7,149.2 206.5,149.2 206.5,149.3 207.3,149.3 207.3,149.1 208.1,149.1 208.1,148.6 208.9,148.6 208.9,148.9 209.8,148.9 209.8,148.5 210.6,148.5 210.6,148.9 211.4,148.9 211.4,149.0 212.2,149.0 212.2,149.0 213.0,149.0 213.0,148.5 213.8,148.5 213.8,149.1 214.6,149.1 214.6,149.2 215.4,149.2 215.4,148.3 216.2,148.3 216.2,1Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="131.8" cy="147.4" r="3.5"><title>#5285: 3.3×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="131.8" y1="54.0" x2="131.8" y2="142.4"/>
|
||||
<circle class="nj-theme-dot" cx="131.8" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="131.8" y="50.0" text-anchor="middle">6</text>
|
||||
<circle class="nj-charts-json-dot" cx="245.5" cy="139.0" r="3.5"><title>#5738: 3.8×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="245.5" y1="54.0" x2="245.5" y2="134.0"/>
|
||||
<circle class="nj-theme-dot" cx="245.5" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="245.5" y="50.0" text-anchor="middle">2</text>
|
||||
<circle class="nj-charts-json-dot" cx="275.6" cy="131.0" r="3.5"><title>#5878: 4.5×</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="281.2" cy="109.6" r="3.5"><title>#5883: 6.8×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="281.2" y1="54.0" x2="281.2" y2="104.6"/>
|
||||
<circle class="nj-theme-dot" cx="281.2" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="281.2" y="50.0" text-anchor="middle">2</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,36 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-from_cbor_twitter nj-blog-tl-from_cbor_twitter-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-from_cbor_twitter">from_cbor() twitter: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-from_cbor_twitter-d">from_cbor() twitter: speedup over 3.12.0 at each of 353 commits, ending at 2.6x. Labeled steps, by theme: 1, 4, U, U.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">from_cbor() twitter</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="137" x2="330" y2="137"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="141">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">4×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,209.1 45.6,209.1 45.6,208.2 46.4,208.2 46.4,208.6 47.2,208.6 47.2,208.0 48.1,208.0 48.1,208.4 48.9,208.4 48.9,208.6 49.7,208.6 49.7,208.3 50.5,208.3 50.5,209.1 51.3,209.1 51.3,207.8 52.1,207.8 52.1,208.5 52.9,208.5 52.9,208.6 53.8,208.6 53.8,208.6 54.6,208.6 54.6,207.7 55.4,207.7 55.4,207.1 56.2,207.1 56.2,207.3 57.0,207.3 57.0,206.9 57.8,206.9 57.8,207.1 58.6,207.1 58.6,207.0 59.4,207.0 59.4,207.1 60.2,207.1 60.2,207.1 61.1,207.1 61.1,207.5 61.9,207.5 61.9,207.5 62.7,207.5 62.7,206.9 63.5,206.9 63.5,207.0 64.3,207.0 64.3,206.2 65.1,206.2 65.1,207.1 65.9,207.1 65.9,208.5 66.8,208.5 66.8,208.0 67.6,208.0 67.6,207.8 68.4,207.8 68.4,208.5 69.2,208.5 69.2,207.8 70.0,207.8 70.0,207.0 70.8,207.0 70.8,208.1 71.6,208.1 71.6,208.2 72.4,208.2 72.4,208.6 73.2,208.6 73.2,208.1 74.1,208.1 74.1,207.2 74.9,207.2 74.9,208.3 75.7,208.3 75.7,207.4 76.5,207.4 76.5,207.9 77.3,207.9 77.3,207.7 78.1,207.7 78.1,208.6 78.9,208.6 78.9,207.3 79.8,207.3 79.8,207.9 80.6,207.9 80.6,208.4 81.4,208.4 81.4,208.5 82.2,208.5 82.2,208.0 83.0,208.0 83.0,207.1 83.8,207.1 83.8,208.1 84.6,208.1 84.6,208.1 85.4,208.1 85.4,207.8 86.2,207.8 86.2,207.9 87.1,207.9 87.1,207.9 87.9,207.9 87.9,208.7 88.7,208.7 88.7,208.1 89.5,208.1 89.5,168.9 90.3,168.9 90.3,170.3 91.1,170.3 91.1,169.9 91.9,169.9 91.9,169.0 92.8,169.0 92.8,169.6 93.6,169.6 93.6,169.1 94.4,169.1 94.4,170.1 95.2,170.1 95.2,168.8 96.0,168.8 96.0,167.9 96.8,167.9 96.8,170.4 97.6,170.4 97.6,169.5 98.4,169.5 98.4,169.7 99.2,169.7 99.2,172.9 100.1,172.9 100.1,170.5 100.9,170.5 100.9,170.4 101.7,170.4 101.7,170.1 102.5,170.1 102.5,170.2 103.3,170.2 103.3,170.7 104.1,170.7 104.1,170.5 104.9,170.5 104.9,170.4 105.8,170.4 105.8,171.1 106.6,171.1 106.6,170.2 107.4,170.2 107.4,168.6 108.2,168.6 108.2,168.9 109.0,168.9 109.0,168.8 109.8,168.8 109.8,170.5 110.6,170.5 110.6,169.2 111.4,169.2 111.4,169.8 112.2,169.8 112.2,168.2 113.1,168.2 113.1,168.3 113.9,168.3 113.9,169.9 114.7,169.9 114.7,170.3 115.5,170.3 115.5,170.5 116.3,170.5 116.3,169.2 117.1,169.2 117.1,170.5 117.9,170.5 117.9,170.1 118.8,170.1 118.8,170.0 119.6,170.0 119.6,170.0 120.4,170.0 120.4,169.7 121.2,169.7 121.2,169.9 122.0,169.9 122.0,169.2 122.8,169.2 122.8,169.6 123.6,169.6 123.6,170.0 124.4,170.0 124.4,170.0 125.3,170.0 125.3,170.5 126.1,170.5 126.1,170.8 126.9,170.8 126.9,170.5 127.7,170.5 127.7,170.8 128.5,170.8 128.5,169.2 129.3,169.2 129.3,128.6 130.1,128.6 130.1,121.0 130.9,121.0 130.9,120.5 131.8,120.5 131.8,120.8 132.6,120.8 132.6,120.9 133.4,120.9 133.4,120.2 134.2,120.2 134.2,116.5 135.0,116.5 135.0,117.5 135.8,117.5 135.8,117.4 136.6,117.4 136.6,118.0 137.4,118.0 137.4,118.3 138.2,118.3 138.2,118.0 139.1,118.0 139.1,120.1 139.9,120.1 139.9,118.9 140.7,118.9 140.7,119.6 141.5,119.6 141.5,119.0 142.3,119.0 142.3,120.9 143.1,120.9 143.1,118.6 143.9,118.6 143.9,121.1 144.8,121.1 144.8,120.1 145.6,120.1 145.6,118.4 146.4,118.4 146.4,119.3 147.2,119.3 147.2,119.0 148.0,119.0 148.0,120.2 148.8,120.2 148.8,119.0 149.6,119.0 149.6,119.4 150.4,119.4 150.4,119.8 151.2,119.8 151.2,120.4 152.1,120.4 152.1,120.6 152.9,120.6 152.9,119.6 153.7,119.6 153.7,118.8 154.5,118.8 154.5,118.4 155.3,118.4 155.3,120.2 156.1,120.2 156.1,119.3 156.9,119.3 156.9,119.9 157.8,119.9 157.8,119.6 158.6,119.6 158.6,119.7 159.4,119.7 159.4,119.2 160.2,119.2 160.2,119.5 161.0,119.5 161.0,118.0 161.8,118.0 161.8,150.3 162.6,150.3 162.6,150.5 163.4,150.5 163.4,150.6 164.2,150.6 164.2,151.3 165.1,151.3 165.1,151.4 165.9,151.4 165.9,150.7 166.7,150.7 166.7,152.1 167.5,152.1 167.5,151.8 168.3,151.8 168.3,152.4 169.1,152.4 169.1,150.6 169.9,150.6 169.9,152.8 170.8,152.8 170.8,154.2 171.6,154.2 171.6,152.8 172.4,152.8 172.4,152.9 173.2,152.9 173.2,153.6 174.0,153.6 174.0,151.7 174.8,151.7 174.8,153.8 175.6,153.8 175.6,151.6 176.4,151.6 176.4,152.6 177.2,152.6 177.2,153.5 178.1,153.5 178.1,151.8 178.9,151.8 178.9,152.7 179.7,152.7 179.7,153.6 180.5,153.6 180.5,152.7 181.3,152.7 181.3,152.5 182.1,152.5 182.1,152.7 182.9,152.7 182.9,151.6 183.8,151.6 183.8,153.2 184.6,153.2 184.6,154.6 185.4,154.6 185.4,152.1 186.2,152.1 186.2,152.9 187.0,152.9 187.0,153.9 187.8,153.9 187.8,153.0 188.6,153.0 188.6,152.6 189.4,152.6 189.4,154.0 190.2,154.0 190.2,154.0 191.1,154.0 191.1,154.3 191.9,154.3 191.9,152.5 192.7,152.5 192.7,154.4 193.5,154.4 193.5,154.2 194.3,154.2 194.3,151.8 195.1,151.8 195.1,154.0 195.9,154.0 195.9,153.0 196.8,153.0 196.8,152.2 197.6,152.2 197.6,153.7 198.4,153.7 198.4,153.8 199.2,153.8 199.2,153.9 200.0,153.9 200.0,155.5 200.8,155.5 200.8,153.4 201.6,153.4 201.6,155.4 202.4,155.4 202.4,152.8 203.2,152.8 203.2,154.0 204.1,154.0 204.1,152.3 204.9,152.3 204.9,153.2 205.7,153.2 205.7,153.5 206.5,153.5 206.5,153.6 207.3,153.6 207.3,154.6 208.1,154.6 208.1,152.7 208.9,152.7 208.9,155.4 209.8,155.4 209.8,152.5 210.6,152.5 210.6,153.3 211.4,153.3 211.4,153.3 212.2,153.3 212.2,154.5 213.0,154.5 213.0,152.6 213.8,152.6 213.8,153.0 214.6,153.0 214.6,154.3 215.4,154.3 215.4,122.0 216.2,122.0 216.2,1Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="89.5" cy="168.9" r="3.5"><title>#5233: 1.47×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="89.5" y1="54.0" x2="89.5" y2="163.9"/>
|
||||
<circle class="nj-theme-dot" cx="89.5" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="89.5" y="50.0" text-anchor="middle">1</text>
|
||||
<circle class="nj-charts-json-dot" cx="129.3" cy="128.6" r="3.5"><title>#5501: 2.2×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="129.3" y1="54.0" x2="129.3" y2="123.6"/>
|
||||
<circle class="nj-theme-dot" cx="129.3" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="129.3" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="161.8" cy="150.3" r="3.5"><title>#5185: 1.76×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="161.8" y1="54.0" x2="161.8" y2="145.3"/>
|
||||
<circle class="nj-theme-dot nj-theme-dot--other" cx="161.8" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="161.8" y="50.0" text-anchor="middle">U</text>
|
||||
<circle class="nj-charts-json-dot" cx="215.4" cy="122.0" r="3.5"><title>#5746: 2.3×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="215.4" y1="54.0" x2="215.4" y2="117.0"/>
|
||||
<circle class="nj-theme-dot nj-theme-dot--other" cx="215.4" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="215.4" y="50.0" text-anchor="middle">U</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,44 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-parse_canada nj-blog-tl-parse_canada-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-parse_canada">parse() canada.json: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-parse_canada-d">parse() canada.json: speedup over 3.12.0 at each of 353 commits, ending at 2.8x. Labeled steps, by theme: 4, 1, 3, 3, 3, 4.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">parse() canada.json</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="137" x2="330" y2="137"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="141">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">4×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,208.2 45.6,208.2 45.6,208.1 46.4,208.1 46.4,207.7 47.2,207.7 47.2,207.2 48.1,207.2 48.1,208.0 48.9,208.0 48.9,208.2 49.7,208.2 49.7,207.8 50.5,207.8 50.5,208.5 51.3,208.5 51.3,207.3 52.1,207.3 52.1,208.0 52.9,208.0 52.9,209.1 53.8,209.1 53.8,208.5 54.6,208.5 54.6,208.1 55.4,208.1 55.4,207.7 56.2,207.7 56.2,209.8 57.0,209.8 57.0,208.6 57.8,208.6 57.8,208.1 58.6,208.1 58.6,208.1 59.4,208.1 59.4,207.0 60.2,207.0 60.2,207.8 61.1,207.8 61.1,207.6 61.9,207.6 61.9,208.1 62.7,208.1 62.7,208.4 63.5,208.4 63.5,207.8 64.3,207.8 64.3,207.4 65.1,207.4 65.1,208.3 65.9,208.3 65.9,207.3 66.8,207.3 66.8,207.8 67.6,207.8 67.6,207.9 68.4,207.9 68.4,207.9 69.2,207.9 69.2,207.5 70.0,207.5 70.0,207.5 70.8,207.5 70.8,208.1 71.6,208.1 71.6,208.1 72.4,208.1 72.4,207.9 73.2,207.9 73.2,207.8 74.1,207.8 74.1,207.1 74.9,207.1 74.9,207.6 75.7,207.6 75.7,207.8 76.5,207.8 76.5,207.3 77.3,207.3 77.3,207.6 78.1,207.6 78.1,208.6 78.9,208.6 78.9,206.5 79.8,206.5 79.8,208.0 80.6,208.0 80.6,208.7 81.4,208.7 81.4,208.0 82.2,208.0 82.2,207.7 83.0,207.7 83.0,208.4 83.8,208.4 83.8,207.9 84.6,207.9 84.6,207.5 85.4,207.5 85.4,207.9 86.2,207.9 86.2,207.4 87.1,207.4 87.1,207.5 87.9,207.5 87.9,208.5 88.7,208.5 88.7,197.5 89.5,197.5 89.5,197.9 90.3,197.9 90.3,196.9 91.1,196.9 91.1,197.0 91.9,197.0 91.9,197.7 92.8,197.7 92.8,196.0 93.6,196.0 93.6,197.3 94.4,197.3 94.4,198.1 95.2,198.1 95.2,197.4 96.0,197.4 96.0,197.0 96.8,197.0 96.8,197.5 97.6,197.5 97.6,197.3 98.4,197.3 98.4,197.7 99.2,197.7 99.2,197.7 100.1,197.7 100.1,197.6 100.9,197.6 100.9,196.9 101.7,196.9 101.7,197.9 102.5,197.9 102.5,197.9 103.3,197.9 103.3,197.6 104.1,197.6 104.1,197.6 104.9,197.6 104.9,197.6 105.8,197.6 105.8,198.1 106.6,198.1 106.6,198.0 107.4,198.0 107.4,195.3 108.2,195.3 108.2,196.6 109.0,196.6 109.0,197.9 109.8,197.9 109.8,197.0 110.6,197.0 110.6,196.3 111.4,196.3 111.4,196.8 112.2,196.8 112.2,196.6 113.1,196.6 113.1,196.6 113.9,196.6 113.9,197.7 114.7,197.7 114.7,197.5 115.5,197.5 115.5,198.1 116.3,198.1 116.3,195.9 117.1,195.9 117.1,197.5 117.9,197.5 117.9,197.6 118.8,197.6 118.8,196.7 119.6,196.7 119.6,197.0 120.4,197.0 120.4,198.0 121.2,198.0 121.2,197.0 122.0,197.0 122.0,197.2 122.8,197.2 122.8,196.6 123.6,196.6 123.6,197.0 124.4,197.0 124.4,197.2 125.3,197.2 125.3,197.6 126.1,197.6 126.1,197.8 126.9,197.8 126.9,197.2 127.7,197.2 127.7,197.6 128.5,197.6 128.5,197.3 129.3,197.3 129.3,197.0 130.1,197.0 130.1,168.6 130.9,168.6 130.9,169.7 131.8,169.7 131.8,170.1 132.6,170.1 132.6,168.9 133.4,168.9 133.4,168.3 134.2,168.3 134.2,169.9 135.0,169.9 135.0,168.7 135.8,168.7 135.8,168.3 136.6,168.3 136.6,169.7 137.4,169.7 137.4,170.9 138.2,170.9 138.2,168.1 139.1,168.1 139.1,170.2 139.9,170.2 139.9,169.1 140.7,169.1 140.7,170.1 141.5,170.1 141.5,168.5 142.3,168.5 142.3,169.7 143.1,169.7 143.1,170.1 143.9,170.1 143.9,169.8 144.8,169.8 144.8,169.1 145.6,169.1 145.6,167.2 146.4,167.2 146.4,169.7 147.2,169.7 147.2,168.6 148.0,168.6 148.0,170.3 148.8,170.3 148.8,169.7 149.6,169.7 149.6,168.7 150.4,168.7 150.4,169.3 151.2,169.3 151.2,172.3 152.1,172.3 152.1,171.2 152.9,171.2 152.9,169.1 153.7,169.1 153.7,167.8 154.5,167.8 154.5,169.3 155.3,169.3 155.3,169.1 156.1,169.1 156.1,168.5 156.9,168.5 156.9,168.7 157.8,168.7 157.8,168.6 158.6,168.6 158.6,169.0 159.4,169.0 159.4,168.5 160.2,168.5 160.2,170.9 161.0,170.9 161.0,169.9 161.8,169.9 161.8,168.0 162.6,168.0 162.6,168.8 163.4,168.8 163.4,168.5 164.2,168.5 164.2,168.5 165.1,168.5 165.1,169.9 165.9,169.9 165.9,169.1 166.7,169.1 166.7,168.6 167.5,168.6 167.5,168.6 168.3,168.6 168.3,169.4 169.1,169.4 169.1,169.1 169.9,169.1 169.9,170.2 170.8,170.2 170.8,178.0 171.6,178.0 171.6,177.3 172.4,177.3 172.4,167.7 173.2,167.7 173.2,168.5 174.0,168.5 174.0,168.7 174.8,168.7 174.8,168.5 175.6,168.5 175.6,168.8 176.4,168.8 176.4,168.0 177.2,168.0 177.2,168.2 178.1,168.2 178.1,167.7 178.9,167.7 178.9,167.5 179.7,167.5 179.7,168.1 180.5,168.1 180.5,168.3 181.3,168.3 181.3,168.1 182.1,168.1 182.1,168.1 182.9,168.1 182.9,167.5 183.8,167.5 183.8,166.5 184.6,166.5 184.6,169.1 185.4,169.1 185.4,168.6 186.2,168.6 186.2,168.5 187.0,168.5 187.0,168.1 187.8,168.1 187.8,167.3 188.6,167.3 188.6,168.0 189.4,168.0 189.4,168.3 190.2,168.3 190.2,168.6 191.1,168.6 191.1,169.0 191.9,169.0 191.9,166.6 192.7,166.6 192.7,169.4 193.5,169.4 193.5,169.3 194.3,169.3 194.3,167.3 195.1,167.3 195.1,168.5 195.9,168.5 195.9,167.1 196.8,167.1 196.8,169.4 197.6,169.4 197.6,168.9 198.4,168.9 198.4,167.4 199.2,167.4 199.2,168.4 200.0,168.4 200.0,168.5 200.8,168.5 200.8,166.9 201.6,166.9 201.6,168.7 202.4,168.7 202.4,165.7 203.2,165.7 203.2,167.0 204.1,167.0 204.1,166.6 204.9,166.6 204.9,167.4 205.7,167.4 205.7,167.6 206.5,167.6 206.5,167.2 207.3,167.2 207.3,167.4 208.1,167.4 208.1,166.6 208.9,166.6 208.9,166.2 209.8,166.2 209.8,168.4 210.6,168.4 210.6,167.2 211.4,167.2 211.4,166.7 212.2,166.7 212.2,166.5 213.0,166.5 213.0,166.0 213.8,166.0 213.8,167.4 214.6,167.4 214.6,167.3 215.4,167.3 215.4,167.3 216.2,167.3 216.2,1Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="88.7" cy="197.5" r="3.5"><title>#5234: 1.11×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="88.7" y1="54.0" x2="88.7" y2="192.5"/>
|
||||
<circle class="nj-theme-dot" cx="88.7" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="88.7" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="130.1" cy="168.6" r="3.5"><title>#5283: 1.47×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="130.1" y1="54.0" x2="130.1" y2="163.6"/>
|
||||
<circle class="nj-theme-dot" cx="130.1" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="130.1" y="50.0" text-anchor="middle">1</text>
|
||||
<circle class="nj-charts-json-dot" cx="172.4" cy="167.7" r="3.5"><title>#5617: 1.48×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="172.4" y1="54.0" x2="172.4" y2="162.7"/>
|
||||
<circle class="nj-theme-dot" cx="172.4" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="172.4" y="50.0" text-anchor="middle">3</text>
|
||||
<circle class="nj-charts-json-dot" cx="245.5" cy="139.8" r="3.5"><title>#5738: 1.95×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="245.5" y1="54.0" x2="245.5" y2="134.8"/>
|
||||
<circle class="nj-theme-dot" cx="245.5" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="245.5" y="50.0" text-anchor="middle">3</text>
|
||||
<circle class="nj-charts-json-dot" cx="271.5" cy="127.4" r="3.5"><title>#5851: 2.2×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="271.5" y1="54.0" x2="271.5" y2="122.4"/>
|
||||
<circle class="nj-theme-dot" cx="271.5" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="271.5" y="50.0" text-anchor="middle">3</text>
|
||||
<circle class="nj-charts-json-dot" cx="285.3" cy="102.2" r="3.5"><title>#5882: 2.8×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="285.3" y1="36.0" x2="285.3" y2="97.2"/>
|
||||
<circle class="nj-theme-dot" cx="285.3" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="285.3" y="32.0" text-anchor="middle">4</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,45 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-parse_citm nj-blog-tl-parse_citm-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-parse_citm">parse() citm_catalog.json: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-parse_citm-d">parse() citm_catalog.json: speedup over 3.12.0 at each of 353 commits, ending at 3.3x. Labeled steps, by theme: 4, 1, 4, 4, 2, 4.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">parse() citm_catalog.json</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="160.667" x2="330" y2="160.667"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="164.667">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="113.333" x2="330" y2="113.333"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="117.333">4×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">8×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,208.2 45.6,208.2 45.6,207.8 46.4,207.8 46.4,207.5 47.2,207.5 47.2,206.5 48.1,206.5 48.1,208.3 48.9,208.3 48.9,207.3 49.7,207.3 49.7,206.8 50.5,206.8 50.5,207.8 51.3,207.8 51.3,206.8 52.1,206.8 52.1,207.3 52.9,207.3 52.9,207.6 53.8,207.6 53.8,207.8 54.6,207.8 54.6,207.0 55.4,207.0 55.4,207.3 56.2,207.3 56.2,207.2 57.0,207.2 57.0,207.4 57.8,207.4 57.8,207.5 58.6,207.5 58.6,207.4 59.4,207.4 59.4,206.6 60.2,206.6 60.2,207.6 61.1,207.6 61.1,207.6 61.9,207.6 61.9,207.2 62.7,207.2 62.7,207.0 63.5,207.0 63.5,207.6 64.3,207.6 64.3,206.7 65.1,206.7 65.1,207.4 65.9,207.4 65.9,206.8 66.8,206.8 66.8,207.3 67.6,207.3 67.6,207.7 68.4,207.7 68.4,207.9 69.2,207.9 69.2,207.2 70.0,207.2 70.0,206.4 70.8,206.4 70.8,207.6 71.6,207.6 71.6,206.4 72.4,206.4 72.4,208.0 73.2,208.0 73.2,207.4 74.1,207.4 74.1,206.5 74.9,206.5 74.9,207.5 75.7,207.5 75.7,207.2 76.5,207.2 76.5,206.9 77.3,206.9 77.3,207.6 78.1,207.6 78.1,207.6 78.9,207.6 78.9,207.0 79.8,207.0 79.8,206.9 80.6,206.9 80.6,208.0 81.4,208.0 81.4,207.6 82.2,207.6 82.2,206.6 83.0,206.6 83.0,206.8 83.8,206.8 83.8,207.3 84.6,207.3 84.6,206.9 85.4,206.9 85.4,207.6 86.2,207.6 86.2,207.1 87.1,207.1 87.1,207.6 87.9,207.6 87.9,207.9 88.7,207.9 88.7,178.2 89.5,178.2 89.5,177.5 90.3,177.5 90.3,177.7 91.1,177.7 91.1,177.6 91.9,177.6 91.9,177.7 92.8,177.7 92.8,177.1 93.6,177.1 93.6,176.8 94.4,176.8 94.4,177.7 95.2,177.7 95.2,177.6 96.0,177.6 96.0,176.8 96.8,176.8 96.8,177.8 97.6,177.8 97.6,177.0 98.4,177.0 98.4,176.8 99.2,176.8 99.2,178.0 100.1,178.0 100.1,178.1 100.9,178.1 100.9,177.6 101.7,177.6 101.7,177.6 102.5,177.6 102.5,177.4 103.3,177.4 103.3,177.6 104.1,177.6 104.1,177.8 104.9,177.8 104.9,177.5 105.8,177.5 105.8,177.9 106.6,177.9 106.6,177.7 107.4,177.7 107.4,175.9 108.2,175.9 108.2,177.5 109.0,177.5 109.0,177.6 109.8,177.6 109.8,177.6 110.6,177.6 110.6,176.9 111.4,176.9 111.4,177.5 112.2,177.5 112.2,177.4 113.1,177.4 113.1,177.4 113.9,177.4 113.9,176.9 114.7,176.9 114.7,177.9 115.5,177.9 115.5,177.3 116.3,177.3 116.3,176.6 117.1,176.6 117.1,177.4 117.9,177.4 117.9,177.5 118.8,177.5 118.8,177.5 119.6,177.5 119.6,177.4 120.4,177.4 120.4,177.0 121.2,177.0 121.2,177.7 122.0,177.7 122.0,176.2 122.8,176.2 122.8,176.9 123.6,176.9 123.6,177.5 124.4,177.5 124.4,177.8 125.3,177.8 125.3,177.8 126.1,177.8 126.1,177.9 126.9,177.9 126.9,177.3 127.7,177.3 127.7,177.5 128.5,177.5 128.5,177.4 129.3,177.4 129.3,177.1 130.1,177.1 130.1,162.5 130.9,162.5 130.9,162.2 131.8,162.2 131.8,161.8 132.6,161.8 132.6,162.2 133.4,162.2 133.4,161.2 134.2,161.2 134.2,160.7 135.0,160.7 135.0,159.4 135.8,159.4 135.8,160.3 136.6,160.3 136.6,160.4 137.4,160.4 137.4,160.6 138.2,160.6 138.2,159.5 139.1,159.5 139.1,160.4 139.9,160.4 139.9,159.6 140.7,159.6 140.7,160.0 141.5,160.0 141.5,159.9 142.3,159.9 142.3,160.2 143.1,160.2 143.1,159.6 143.9,159.6 143.9,160.8 144.8,160.8 144.8,160.1 145.6,160.1 145.6,159.1 146.4,159.1 146.4,159.7 147.2,159.7 147.2,159.9 148.0,159.9 148.0,160.5 148.8,160.5 148.8,160.2 149.6,160.2 149.6,159.9 150.4,159.9 150.4,160.5 151.2,160.5 151.2,160.5 152.1,160.5 152.1,160.6 152.9,160.6 152.9,159.7 153.7,159.7 153.7,159.5 154.5,159.5 154.5,160.0 155.3,160.0 155.3,160.2 156.1,160.2 156.1,160.0 156.9,160.0 156.9,160.6 157.8,160.6 157.8,159.9 158.6,159.9 158.6,160.2 159.4,160.2 159.4,160.1 160.2,160.1 160.2,160.8 161.0,160.8 161.0,159.2 161.8,159.2 161.8,159.6 162.6,159.6 162.6,159.2 163.4,159.2 163.4,160.0 164.2,160.0 164.2,159.4 165.1,159.4 165.1,159.6 165.9,159.6 165.9,159.5 166.7,159.5 166.7,160.1 167.5,160.1 167.5,159.0 168.3,159.0 168.3,159.4 169.1,159.4 169.1,160.2 169.9,160.2 169.9,161.4 170.8,161.4 170.8,161.7 171.6,161.7 171.6,161.6 172.4,161.6 172.4,160.3 173.2,160.3 173.2,161.1 174.0,161.1 174.0,161.2 174.8,161.2 174.8,161.7 175.6,161.7 175.6,161.2 176.4,161.2 176.4,160.4 177.2,160.4 177.2,161.6 178.1,161.6 178.1,160.6 178.9,160.6 178.9,161.4 179.7,161.4 179.7,161.3 180.5,161.3 180.5,161.3 181.3,161.3 181.3,161.7 182.1,161.7 182.1,161.2 182.9,161.2 182.9,160.1 183.8,160.1 183.8,160.9 184.6,160.9 184.6,161.5 185.4,161.5 185.4,160.6 186.2,160.6 186.2,161.9 187.0,161.9 187.0,161.4 187.8,161.4 187.8,160.1 188.6,160.1 188.6,160.6 189.4,160.6 189.4,162.0 190.2,162.0 190.2,161.5 191.1,161.5 191.1,162.0 191.9,162.0 191.9,161.3 192.7,161.3 192.7,162.3 193.5,162.3 193.5,162.1 194.3,162.1 194.3,160.8 195.1,160.8 195.1,161.5 195.9,161.5 195.9,161.4 196.8,161.4 196.8,162.2 197.6,162.2 197.6,161.4 198.4,161.4 198.4,161.4 199.2,161.4 199.2,161.8 200.0,161.8 200.0,160.7 200.8,160.7 200.8,160.5 201.6,160.5 201.6,160.5 202.4,160.5 202.4,159.3 203.2,159.3 203.2,159.4 204.1,159.4 204.1,160.4 204.9,160.4 204.9,160.1 205.7,160.1 205.7,160.4 206.5,160.4 206.5,160.4 207.3,160.4 207.3,160.8 208.1,160.8 208.1,159.8 208.9,159.8 208.9,159.4 209.8,159.4 209.8,160.5 210.6,160.5 210.6,160.1 211.4,160.1 211.4,160.7 212.2,160.7 212.2,160.6 213.0,160.6 213.0,159.5 213.8,159.5 213.8,161.1 214.6,161.1 214.6,161.3 215.4,161.3 215.4,161.0 216.2,161.0 216.2,1Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="88.7" cy="178.2" r="3.5"><title>#5234: 1.55×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="88.7" y1="54.0" x2="88.7" y2="173.2"/>
|
||||
<circle class="nj-theme-dot" cx="88.7" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="88.7" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="130.1" cy="162.5" r="3.5"><title>#5283: 1.95×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="130.1" y1="54.0" x2="130.1" y2="157.5"/>
|
||||
<circle class="nj-theme-dot" cx="130.1" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="130.1" y="50.0" text-anchor="middle">1</text>
|
||||
<circle class="nj-charts-json-dot" cx="222.8" cy="155.4" r="3.5"><title>#5592: 2.2×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="222.8" y1="54.0" x2="222.8" y2="150.4"/>
|
||||
<circle class="nj-theme-dot" cx="222.8" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="222.8" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="243.1" cy="147.1" r="3.5"><title>#5809: 2.4×</title></circle>
|
||||
<circle class="nj-charts-json-dot" cx="243.9" cy="138.2" r="3.5"><title>#5810: 2.8×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="243.9" y1="36.0" x2="243.9" y2="133.2"/>
|
||||
<circle class="nj-theme-dot" cx="234.9" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="234.9" y="32.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-theme-dot" cx="252.9" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="252.9" y="32.0" text-anchor="middle">2</text>
|
||||
<circle class="nj-charts-json-dot" cx="285.3" cy="125.7" r="3.5"><title>#5882: 3.3×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="285.3" y1="54.0" x2="285.3" y2="120.7"/>
|
||||
<circle class="nj-theme-dot" cx="285.3" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="285.3" y="50.0" text-anchor="middle">4</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,28 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-parse_twitter_ifstream nj-blog-tl-parse_twitter_ifstream-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-parse_twitter_ifstream">parse() twitter.json, std::ifstream: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-parse_twitter_ifstream-d">parse() twitter.json, std::ifstream: speedup over 3.12.0 at each of 353 commits, ending at 2.2x. Labeled steps, by theme: 1, 1.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">parse() twitter.json, std::ifstream</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="137" x2="330" y2="137"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="141">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">4×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,209.3 45.6,209.3 45.6,206.6 46.4,206.6 46.4,208.3 47.2,208.3 47.2,205.9 48.1,205.9 48.1,209.3 48.9,209.3 48.9,208.3 49.7,208.3 49.7,207.9 50.5,207.9 50.5,209.4 51.3,209.4 51.3,205.8 52.1,205.8 52.1,206.7 52.9,206.7 52.9,209.2 53.8,209.2 53.8,208.1 54.6,208.1 54.6,206.9 55.4,206.9 55.4,207.5 56.2,207.5 56.2,207.5 57.0,207.5 57.0,207.6 57.8,207.6 57.8,206.9 58.6,206.9 58.6,206.9 59.4,206.9 59.4,208.4 60.2,208.4 60.2,208.6 61.1,208.6 61.1,209.1 61.9,209.1 61.9,207.7 62.7,207.7 62.7,207.0 63.5,207.0 63.5,206.7 64.3,206.7 64.3,206.1 65.1,206.1 65.1,207.5 65.9,207.5 65.9,206.4 66.8,206.4 66.8,206.7 67.6,206.7 67.6,206.8 68.4,206.8 68.4,209.3 69.2,209.3 69.2,206.7 70.0,206.7 70.0,206.8 70.8,206.8 70.8,206.6 71.6,206.6 71.6,206.8 72.4,206.8 72.4,209.2 73.2,209.2 73.2,207.6 74.1,207.6 74.1,205.9 74.9,205.9 74.9,209.1 75.7,209.1 75.7,206.6 76.5,206.6 76.5,207.4 77.3,207.4 77.3,207.0 78.1,207.0 78.1,209.1 78.9,209.1 78.9,205.8 79.8,205.8 79.8,206.9 80.6,206.9 80.6,208.0 81.4,208.0 81.4,208.5 82.2,208.5 82.2,206.6 83.0,206.6 83.0,206.0 83.8,206.0 83.8,207.9 84.6,207.9 84.6,206.6 85.4,206.6 85.4,206.5 86.2,206.5 86.2,206.6 87.1,206.6 87.1,207.2 87.9,207.2 87.9,208.0 88.7,208.0 88.7,208.1 89.5,208.1 89.5,206.7 90.3,206.7 90.3,207.8 91.1,207.8 91.1,206.7 91.9,206.7 91.9,208.1 92.8,208.1 92.8,205.9 93.6,205.9 93.6,206.8 94.4,206.8 94.4,208.0 95.2,208.0 95.2,207.3 96.0,207.3 96.0,206.7 96.8,206.7 96.8,209.3 97.6,209.3 97.6,206.5 98.4,206.5 98.4,207.2 99.2,207.2 99.2,208.2 100.1,208.2 100.1,209.3 100.9,209.3 100.9,207.8 101.7,207.8 101.7,206.9 102.5,206.9 102.5,206.7 103.3,206.7 103.3,209.0 104.1,209.0 104.1,208.0 104.9,208.0 104.9,208.1 105.8,208.1 105.8,209.1 106.6,209.1 106.6,208.1 107.4,208.1 107.4,205.6 108.2,205.6 108.2,207.0 109.0,207.0 109.0,206.7 109.8,206.7 109.8,207.9 110.6,207.9 110.6,206.7 111.4,206.7 111.4,206.9 112.2,206.9 112.2,206.8 113.1,206.8 113.1,206.4 113.9,206.4 113.9,207.1 114.7,207.1 114.7,208.6 115.5,208.6 115.5,208.7 116.3,208.7 116.3,206.6 117.1,206.6 117.1,209.3 117.9,209.3 117.9,208.0 118.8,208.0 118.8,206.7 119.6,206.7 119.6,207.7 120.4,207.7 120.4,206.9 121.2,206.9 121.2,208.8 122.0,208.8 122.0,208.7 122.8,208.7 122.8,207.7 123.6,207.7 123.6,208.8 124.4,208.8 124.4,207.8 125.3,207.8 125.3,210.3 126.1,210.3 126.1,208.9 126.9,208.9 126.9,208.9 127.7,208.9 127.7,209.0 128.5,209.0 128.5,208.0 129.3,208.0 129.3,207.7 130.1,207.7 130.1,208.3 130.9,208.3 130.9,207.0 131.8,207.0 131.8,207.2 132.6,207.2 132.6,207.5 133.4,207.5 133.4,208.0 134.2,208.0 134.2,207.6 135.0,207.6 135.0,207.9 135.8,207.9 135.8,207.6 136.6,207.6 136.6,208.5 137.4,208.5 137.4,209.2 138.2,209.2 138.2,206.3 139.1,206.3 139.1,208.7 139.9,208.7 139.9,207.6 140.7,207.6 140.7,207.4 141.5,207.4 141.5,207.5 142.3,207.5 142.3,209.0 143.1,209.0 143.1,206.9 143.9,206.9 143.9,209.3 144.8,209.3 144.8,209.9 145.6,209.9 145.6,207.0 146.4,207.0 146.4,207.3 147.2,207.3 147.2,208.1 148.0,208.1 148.0,209.8 148.8,209.8 148.8,208.1 149.6,208.1 149.6,208.1 150.4,208.1 150.4,208.5 151.2,208.5 151.2,208.2 152.1,208.2 152.1,210.4 152.9,210.4 152.9,207.7 153.7,207.7 153.7,207.2 154.5,207.2 154.5,206.7 155.3,206.7 155.3,209.9 156.1,209.9 156.1,206.6 156.9,206.6 156.9,209.9 157.8,209.9 157.8,208.8 158.6,208.8 158.6,208.8 159.4,208.8 159.4,209.5 160.2,209.5 160.2,208.9 161.0,208.9 161.0,206.4 161.8,206.4 161.8,207.2 162.6,207.2 162.6,207.0 163.4,207.0 163.4,207.2 164.2,207.2 164.2,206.6 165.1,206.6 165.1,207.2 165.9,207.2 165.9,208.0 166.7,208.0 166.7,207.6 167.5,207.6 167.5,207.9 168.3,207.9 168.3,207.5 169.1,207.5 169.1,205.6 169.9,205.6 169.9,208.0 170.8,208.0 170.8,209.7 171.6,209.7 171.6,207.9 172.4,207.9 172.4,207.6 173.2,207.6 173.2,208.5 174.0,208.5 174.0,207.9 174.8,207.9 174.8,210.4 175.6,210.4 175.6,206.7 176.4,206.7 176.4,207.7 177.2,207.7 177.2,209.2 178.1,209.2 178.1,206.8 178.9,206.8 178.9,209.3 179.7,209.3 179.7,208.0 180.5,208.0 180.5,208.0 181.3,208.0 181.3,207.9 182.1,207.9 182.1,208.2 182.9,208.2 182.9,207.9 183.8,207.9 183.8,207.0 184.6,207.0 184.6,208.8 185.4,208.8 185.4,208.0 186.2,208.0 186.2,208.0 187.0,208.0 187.0,209.2 187.8,209.2 187.8,206.7 188.6,206.7 188.6,206.7 189.4,206.7 189.4,208.5 190.2,208.5 190.2,208.9 191.1,208.9 191.1,210.1 191.9,210.1 191.9,206.4 192.7,206.4 192.7,209.4 193.5,209.4 193.5,210.1 194.3,210.1 194.3,207.6 195.1,207.6 195.1,209.5 195.9,209.5 195.9,208.7 196.8,208.7 196.8,211.1 197.6,211.1 197.6,210.1 198.4,210.1 198.4,211.7 199.2,211.7 199.2,208.8 200.0,208.8 200.0,209.2 200.8,209.2 200.8,207.7 201.6,207.7 201.6,208.1 202.4,208.1 202.4,206.4 203.2,206.4 203.2,206.7 204.1,206.7 204.1,207.3 204.9,207.3 204.9,207.8 205.7,207.8 205.7,208.7 206.5,208.7 206.5,210.1 207.3,210.1 207.3,210.0 208.1,210.0 208.1,206.9 208.9,206.9 208.9,209.0 209.8,209.0 209.8,208.7 210.6,208.7 210.6,209.1 211.4,209.1 211.4,208.6 212.2,208.6 212.2,208.9 213.0,208.9 213.0,207.3 213.8,207.3 213.8,208.9 214.6,208.9 214.6,209.2 215.4,209.2 215.4,207.3 216.2,207.3 216.2,2Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="262.6" cy="138.8" r="3.5"><title>#5828: 1.97×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="262.6" y1="54.0" x2="262.6" y2="133.8"/>
|
||||
<circle class="nj-theme-dot" cx="262.6" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="262.6" y="50.0" text-anchor="middle">1</text>
|
||||
<circle class="nj-charts-json-dot" cx="279.6" cy="127.0" r="3.5"><title>#5884: 2.2×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="279.6" y1="36.0" x2="279.6" y2="122.0"/>
|
||||
<circle class="nj-theme-dot" cx="279.6" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="279.6" y="32.0" text-anchor="middle">1</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 10 KiB |
@@ -1,34 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--timeline" viewBox="0 0 340 270" role="img" aria-labelledby="nj-blog-tl-to_cbor_twitter nj-blog-tl-to_cbor_twitter-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-tl-to_cbor_twitter">to_cbor() twitter: speedup over 3.12.0 by commit</title>
|
||||
<desc id="nj-blog-tl-to_cbor_twitter-d">to_cbor() twitter: speedup over 3.12.0 at each of 353 commits, ending at 5.0x. Labeled steps, by theme: 4, 6, 6.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">to_cbor() twitter</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="212">1×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="160.667" x2="330" y2="160.667"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="164.667">2×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="113.333" x2="330" y2="113.333"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="117.333">4×</text>
|
||||
<line class="nj-charts-grid" x1="44" y1="66" x2="330" y2="66"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="38" y="70">8×</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="44" y2="212"/>
|
||||
<text class="nj-charts-tick" x="44" y="225">3.12.0</text>
|
||||
<line class="nj-charts-axis" x1="117.938" y1="208" x2="117.938" y2="212"/>
|
||||
<text class="nj-charts-tick" x="117.938" y="225">Sep 2026</text>
|
||||
<line class="nj-charts-axis" x1="198.375" y1="208" x2="198.375" y2="212"/>
|
||||
<text class="nj-charts-tick" x="198.375" y="225">Oct</text>
|
||||
<polyline class="nj-charts-json" points="44.0,208.0 44.8,208.0 44.8,208.0 45.6,208.0 45.6,204.9 46.4,204.9 46.4,205.2 47.2,205.2 47.2,204.7 48.1,204.7 48.1,205.2 48.9,205.2 48.9,205.0 49.7,205.0 49.7,204.9 50.5,204.9 50.5,205.0 51.3,205.0 51.3,205.0 52.1,205.0 52.1,205.1 52.9,205.1 52.9,205.4 53.8,205.4 53.8,205.0 54.6,205.0 54.6,205.2 55.4,205.2 55.4,211.6 56.2,211.6 56.2,206.8 57.0,206.8 57.0,204.2 57.8,204.2 57.8,207.6 58.6,207.6 58.6,204.1 59.4,204.1 59.4,203.8 60.2,203.8 60.2,204.2 61.1,204.2 61.1,205.1 61.9,205.1 61.9,204.4 62.7,204.4 62.7,204.3 63.5,204.3 63.5,204.0 64.3,204.0 64.3,202.7 65.1,202.7 65.1,204.2 65.9,204.2 65.9,204.2 66.8,204.2 66.8,204.2 67.6,204.2 67.6,204.4 68.4,204.4 68.4,206.2 69.2,206.2 69.2,204.3 70.0,204.3 70.0,204.1 70.8,204.1 70.8,204.3 71.6,204.3 71.6,204.3 72.4,204.3 72.4,204.3 73.2,204.3 73.2,204.3 74.1,204.3 74.1,204.4 74.9,204.4 74.9,204.8 75.7,204.8 75.7,208.4 76.5,208.4 76.5,203.5 77.3,203.5 77.3,206.2 78.1,206.2 78.1,204.4 78.9,204.4 78.9,203.2 79.8,203.2 79.8,204.1 80.6,204.1 80.6,204.2 81.4,204.2 81.4,203.7 82.2,203.7 82.2,204.2 83.0,204.2 83.0,203.2 83.8,203.2 83.8,204.2 84.6,204.2 84.6,204.4 85.4,204.4 85.4,203.8 86.2,203.8 86.2,204.4 87.1,204.4 87.1,204.7 87.9,204.7 87.9,204.6 88.7,204.6 88.7,208.7 89.5,208.7 89.5,205.2 90.3,205.2 90.3,205.5 91.1,205.5 91.1,205.2 91.9,205.2 91.9,205.3 92.8,205.3 92.8,206.8 93.6,206.8 93.6,204.6 94.4,204.6 94.4,205.5 95.2,205.5 95.2,205.1 96.0,205.1 96.0,204.7 96.8,204.7 96.8,205.7 97.6,205.7 97.6,205.0 98.4,205.0 98.4,204.9 99.2,204.9 99.2,206.5 100.1,206.5 100.1,205.6 100.9,205.6 100.9,205.0 101.7,205.0 101.7,209.2 102.5,209.2 102.5,205.9 103.3,205.9 103.3,206.5 104.1,206.5 104.1,205.5 104.9,205.5 104.9,205.3 105.8,205.3 105.8,205.3 106.6,205.3 106.6,205.1 107.4,205.1 107.4,204.4 108.2,204.4 108.2,204.6 109.0,204.6 109.0,204.8 109.8,204.8 109.8,204.2 110.6,204.2 110.6,203.8 111.4,203.8 111.4,204.4 112.2,204.4 112.2,202.8 113.1,202.8 113.1,203.5 113.9,203.5 113.9,204.0 114.7,204.0 114.7,204.3 115.5,204.3 115.5,202.9 116.3,202.9 116.3,203.3 117.1,203.3 117.1,204.4 117.9,204.4 117.9,204.5 118.8,204.5 118.8,204.1 119.6,204.1 119.6,208.3 120.4,208.3 120.4,203.8 121.2,203.8 121.2,207.0 122.0,207.0 122.0,205.9 122.8,205.9 122.8,205.4 123.6,205.4 123.6,205.3 124.4,205.3 124.4,205.8 125.3,205.8 125.3,205.4 126.1,205.4 126.1,205.6 126.9,205.6 126.9,206.3 127.7,206.3 127.7,205.5 128.5,205.5 128.5,204.8 129.3,204.8 129.3,204.6 130.1,204.6 130.1,206.1 130.9,206.1 130.9,204.6 131.8,204.6 131.8,204.1 132.6,204.1 132.6,204.3 133.4,204.3 133.4,205.6 134.2,205.6 134.2,203.9 135.0,203.9 135.0,204.0 135.8,204.0 135.8,203.9 136.6,203.9 136.6,204.6 137.4,204.6 137.4,204.1 138.2,204.1 138.2,203.9 139.1,203.9 139.1,204.8 139.9,204.8 139.9,203.2 140.7,203.2 140.7,203.3 141.5,203.3 141.5,204.7 142.3,204.7 142.3,208.3 143.1,208.3 143.1,204.3 143.9,204.3 143.9,207.4 144.8,207.4 144.8,204.4 145.6,204.4 145.6,208.2 146.4,208.2 146.4,205.0 147.2,205.0 147.2,204.9 148.0,204.9 148.0,208.8 148.8,208.8 148.8,207.9 149.6,207.9 149.6,206.2 150.4,206.2 150.4,204.2 151.2,204.2 151.2,204.1 152.1,204.1 152.1,204.2 152.9,204.2 152.9,202.2 153.7,202.2 153.7,205.6 154.5,205.6 154.5,203.0 155.3,203.0 155.3,203.4 156.1,203.4 156.1,202.7 156.9,202.7 156.9,203.6 157.8,203.6 157.8,203.3 158.6,203.3 158.6,203.2 159.4,203.2 159.4,204.9 160.2,204.9 160.2,202.9 161.0,202.9 161.0,202.2 161.8,202.2 161.8,202.5 162.6,202.5 162.6,202.9 163.4,202.9 163.4,202.9 164.2,202.9 164.2,202.3 165.1,202.3 165.1,202.9 165.9,202.9 165.9,203.7 166.7,203.7 166.7,204.1 167.5,204.1 167.5,203.9 168.3,203.9 168.3,203.7 169.1,203.7 169.1,203.3 169.9,203.3 169.9,203.8 170.8,203.8 170.8,205.0 171.6,205.0 171.6,208.0 172.4,208.0 172.4,205.1 173.2,205.1 173.2,206.5 174.0,206.5 174.0,205.4 174.8,205.4 174.8,205.4 175.6,205.4 175.6,207.0 176.4,207.0 176.4,204.9 177.2,204.9 177.2,205.4 178.1,205.4 178.1,203.6 178.9,203.6 178.9,205.7 179.7,205.7 179.7,204.5 180.5,204.5 180.5,205.0 181.3,205.0 181.3,205.2 182.1,205.2 182.1,204.9 182.9,204.9 182.9,204.5 183.8,204.5 183.8,204.9 184.6,204.9 184.6,205.3 185.4,205.3 185.4,203.9 186.2,203.9 186.2,204.8 187.0,204.8 187.0,204.8 187.8,204.8 187.8,203.6 188.6,203.6 188.6,203.4 189.4,203.4 189.4,203.8 190.2,203.8 190.2,205.1 191.1,205.1 191.1,205.5 191.9,205.5 191.9,204.0 192.7,204.0 192.7,204.9 193.5,204.9 193.5,205.0 194.3,205.0 194.3,206.4 195.1,206.4 195.1,205.1 195.9,205.1 195.9,204.5 196.8,204.5 196.8,204.8 197.6,204.8 197.6,205.2 198.4,205.2 198.4,205.0 199.2,205.0 199.2,204.6 200.0,204.6 200.0,203.9 200.8,203.9 200.8,203.5 201.6,203.5 201.6,203.6 202.4,203.6 202.4,204.2 203.2,204.2 203.2,205.9 204.1,205.9 204.1,205.2 204.9,205.2 204.9,204.8 205.7,204.8 205.7,207.3 206.5,207.3 206.5,205.2 207.3,205.2 207.3,208.6 208.1,208.6 208.1,204.3 208.9,204.3 208.9,203.9 209.8,203.9 209.8,203.2 210.6,203.2 210.6,203.9 211.4,203.9 211.4,205.9 212.2,205.9 212.2,204.8 213.0,204.8 213.0,204.7 213.8,204.7 213.8,203.6 214.6,203.6 214.6,203.7 215.4,203.7 215.4,208.2 216.2,208.2 216.2,2Line truncated
|
||||
<circle class="nj-charts-json-dot" cx="234.9" cy="153.7" r="3.5"><title>#5328: 2.2×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="234.9" y1="54.0" x2="234.9" y2="148.7"/>
|
||||
<circle class="nj-theme-dot" cx="234.9" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="234.9" y="50.0" text-anchor="middle">4</text>
|
||||
<circle class="nj-charts-json-dot" cx="269.9" cy="123.4" r="3.5"><title>#5824: 3.5×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="269.9" y1="54.0" x2="269.9" y2="118.4"/>
|
||||
<circle class="nj-theme-dot" cx="269.9" cy="46.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="269.9" y="50.0" text-anchor="middle">6</text>
|
||||
<circle class="nj-charts-json-dot" cx="282.1" cy="96.9" r="3.5"><title>#5885: 5.1×</title></circle>
|
||||
<line class="nj-charts-grid" stroke-dasharray="2 2" x1="282.1" y1="36.0" x2="282.1" y2="91.9"/>
|
||||
<circle class="nj-theme-dot" cx="282.1" cy="28.0" r="7.5"/>
|
||||
<text class="nj-theme-num" x="282.1" y="32.0" text-anchor="middle">6</text>
|
||||
<line class="nj-charts-axis" x1="44" y1="208" x2="330" y2="208"/>
|
||||
<text class="nj-charts-note" x="8" y="262">speedup over 3.12.0 (log scale), more is better</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,379 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog nj-charts--heat" viewBox="0 0 784 510" role="img" aria-labelledby="nj-blog-uc-mac nj-blog-uc-mac-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-uc-mac">Use cases: time of each library relative to the fastest, Apple M1 Max</title>
|
||||
<desc id="nj-blog-uc-mac-d">Table of relative times, libraries by use case. nlohmann/json json_document validate: 1.00; nlohmann/json json_document sum: 1.00; nlohmann/json json_document select: 1.00; nlohmann/json json_document edit: 1.00 (0.85 doing less, N); nlohmann/json json_document minify: 1.00 (0.85 doing less, N); nlohmann/json json_document write: 1.00 (0.71 doing less, N); yyjson validate: 1.37; yyjson sum: 1.11; yyjson select: 1.25; yyjson edit: 1.45; yyjson minify: 1.23 (1.16 doing less, N); yyjson write: 1.26; simdjson validate: 1.52; simdjson sum: 1.20; simdjson select: 1.33 (0.75 doing less, P); simdjson edit: n/a; simdjson minify: 1.73 (0.18 doing less, P); simdjson write: 2.41; sonic-rs (Rust) validate: 1.93; sonic-rs (Rust) sum: 1.53; sonic-rs (Rust) select: 1.83; sonic-rs (Rust) edit: 2.08; sonic-rs (Rust) minify: 1.93; sonic-rs (Rust) write: 2.38; sonic-cpp validate: no fully validating way (2.53 doing less, U); sonic-cpp sum: no fully validating way (1.86 doing less, U); sonic-cpp select: no fully validating way (2.31 doing less, U); sonic-cpp edit: no fully validating way (1.68 doing less, U); sonic-cpp minify: no fully validating way (2.03 doing less, U); sonic-cpp write: 1.59; simd-json (Rust) validate: 2.07; simd-json (Rust) sum: 1.62; simd-json (Rust) select: 2.38; simd-json (Rust) edit: 2.84; simd-json (Rust) minify: 3.40; simd-json (Rust) write: 3.10; Glaze validate: 2.04; Glaze sum: 3.85; Glaze select: 1.79 (0.82 doing less, P); Glaze edit: 4.41; Glaze minify: 5.19 (1.03 doing less, P); Glaze write: 2.23; Boost.J​SON validate: 2.56; Boost.J​SON sum: 1.99; Boost.J​SON select: 3.27; Boost.J​SON edit: 3.21; Boost.J​SON minify: 3.87; Boost.J​SON write: 3.75; serde_json (Rust) validate: 2.46 (2.23 doing less, U); serde_json (Rust) sum: 2.59; serde_json (Rust) select: 2.39 (2.24 doing less, U); serde_json (Rust) edit: 4.99; serde_json (Rust) minify: 5.85; serde_json (Rust) write: 2.95; nlohmann/json json validate: 2.71; nlohmann/json json sum: 1.96; nlohmann/json json select: 6.87; nlohmann/json json edit: 3.73; nlohmann/json json minify: 4.89; nlohmann/json json write: 2.10; RapidJSON validate: 4.72 (3.09 doing less, U); RapidJSON sum: 4.15 (2.85 doing less, U); RapidJSON select: 5.91 (3.82 doing less, U); RapidJSON edit: 4.82 (3.77 doing less, U); RapidJSON minify: 4.86 (3.60 doing less, U N); RapidJSON write: 5.88.</desc>
|
||||
<text class="nj-charts-tick" x="270" y="34">validate</text>
|
||||
<text class="nj-charts-tick" x="362" y="34">sum</text>
|
||||
<text class="nj-charts-tick" x="454" y="34">select</text>
|
||||
<text class="nj-charts-tick" x="546" y="34">edit</text>
|
||||
<text class="nj-charts-tick" x="638" y="34">minify</text>
|
||||
<text class="nj-charts-tick" x="730" y="34">write</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="66" text-anchor="end">nlohmann/json json_document</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · validate 1.00× the time of the fastest library (fully validating) way: accept twitter.json: 170 µs citm_catalog.json: 313 µs canada.json: 886 µs jeopardy.json: 20,873 µs">
|
||||
<rect class="nj-heat-0" x="225" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · sum 1.00× the time of the fastest library (fully validating) way: parse twitter.json: 224 µs citm_catalog.json: 485 µs canada.json: 1,816 µs jeopardy.json: 28,987 µs">
|
||||
<rect class="nj-heat-0" x="317" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · select 1.00× the time of the fastest library (fully validating) way: parse twitter.json: 184 µs citm_catalog.json: 363 µs canada.json: 956 µs jeopardy.json: 24,991 µs">
|
||||
<rect class="nj-heat-0" x="409" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit 1.00× the time of the fastest library (fully validating) way: editable twitter.json: 291 µs citm_catalog.json: 560 µs canada.json: 2,765 µs jeopardy.json: 58,057 µs">
|
||||
<rect class="nj-heat-0" x="501" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit, checking less 0.85× the time of the fastest fully validating library twitter.json: 283 µs · editable (source numbers) (validates fully) citm_catalog.json: 560 µs · editable (validates fully) canada.json: 1,484 µs · editable (source numbers) (validates fully) jeopardy.json: 57,635 µs · editable (source numbers) (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="547" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="60" text-anchor="middle">0.85</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify 1.00× the time of the fastest library (fully validating) way: parse + dump twitter.json: 259 µs citm_catalog.json: 493 µs canada.json: 2,582 µs jeopardy.json: 37,882 µs">
|
||||
<rect class="nj-heat-0" x="593" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify, checking less 0.85× the time of the fastest fully validating library twitter.json: 252 µs · parse + dump (source numbers) (validates fully) citm_catalog.json: 493 µs · parse + dump (validates fully) canada.json: 1,360 µs · parse + dump (source numbers) (validates fully) jeopardy.json: 37,817 µs · parse + dump (source numbers) (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="639" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="60" text-anchor="middle">0.85</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write 1.00× the time of the fastest library (fully validating) way: dump twitter.json: 74.3 µs citm_catalog.json: 134 µs canada.json: 1,621 µs jeopardy.json: 14,757 µs">
|
||||
<rect class="nj-heat-0" x="685" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="707.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write, checking less 0.71× the time of the fastest fully validating library twitter.json: 74.3 µs · dump (validates fully) citm_catalog.json: 134 µs · dump (validates fully) canada.json: 401 µs · dump (source numbers) (validates fully) jeopardy.json: 14,757 µs · dump (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="731" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="752.5" y="60" text-anchor="middle">0.71</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="752.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="102" text-anchor="end">yyjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · validate 1.37× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 172 µs citm_catalog.json: 451 µs canada.json: 1,457 µs jeopardy.json: 30,240 µs">
|
||||
<rect class="nj-heat-1" x="225" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="102" text-anchor="middle">1.37</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · sum 1.11× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 219 µs citm_catalog.json: 551 µs canada.json: 1,906 µs jeopardy.json: 37,512 µs">
|
||||
<rect class="nj-heat-0" x="317" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="102" text-anchor="middle">1.11</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · select 1.25× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 178 µs citm_catalog.json: 456 µs canada.json: 1,461 µs jeopardy.json: 32,514 µs">
|
||||
<rect class="nj-heat-1" x="409" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="102" text-anchor="middle">1.25</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · edit 1.45× the time of the fastest library (fully validating) way: insitu (copy untimed) + mut copy twitter.json: 427 µs citm_catalog.json: 882 µs canada.json: 3,642 µs jeopardy.json: 84,239 µs">
|
||||
<rect class="nj-heat-1" x="501" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="102" text-anchor="middle">1.45</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify 1.23× the time of the fastest library (fully validating) way: insitu (copy untimed) + write twitter.json: 279 µs citm_catalog.json: 625 µs canada.json: 3,196 µs jeopardy.json: 50,821 µs">
|
||||
<rect class="nj-heat-1" x="593" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="102" text-anchor="middle">1.23</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify, checking less 1.16× the time of the fastest fully validating library twitter.json: 279 µs · insitu (copy untimed) + write (validates fully) citm_catalog.json: 625 µs · insitu (copy untimed) + write (validates fully) canada.json: 2,550 µs · read (raw numbers) + write (validates fully) jeopardy.json: 50,821 µs · insitu (copy untimed) + write (validates fully) copies each number's text instead of formatting it (YYJSON_READ_NUMBER_AS_RAW)">
|
||||
<rect class="nj-heat-1" x="639" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="96" text-anchor="middle">1.16</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="109" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · write 1.26× the time of the fastest library (fully validating) way: write twitter.json: 103 µs citm_catalog.json: 169 µs canada.json: 1,731 µs jeopardy.json: 20,087 µs">
|
||||
<rect class="nj-heat-1" x="685" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="102" text-anchor="middle">1.26</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="138" text-anchor="end">simdjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · validate 1.52× the time of the fastest library (fully validating) way: D​OM twitter.json: 212 µs citm_catalog.json: 452 µs canada.json: 1,888 µs jeopardy.json: 28,843 µs">
|
||||
<rect class="nj-heat-2" x="225" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="138" text-anchor="middle">1.52</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · sum 1.20× the time of the fastest library (fully validating) twitter.json: 249 µs · D​OM citm_catalog.json: 571 µs · On-Demand canada.json: 2,374 µs · On-Demand jeopardy.json: 35,111 µs · D​OM">
|
||||
<rect class="nj-heat-1" x="317" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="138" text-anchor="middle">1.20</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select 1.33× the time of the fastest library (fully validating) way: D​OM twitter.json: 196 µs citm_catalog.json: 450 µs canada.json: 1,886 µs jeopardy.json: 30,504 µs">
|
||||
<rect class="nj-heat-1" x="409" y="117" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="138" text-anchor="middle">1.33</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select, checking less 0.75× the time of the fastest fully validating library twitter.json: 127 µs · On-Demand structs citm_catalog.json: 354 µs · On-Demand canada.json: 566 µs · On-Demand (key selectors) jeopardy.json: 19,562 µs · On-Demand reads lazily: On-Demand reads only what you ask for and steps over the rest by matching brackets">
|
||||
<rect class="nj-heat-0" x="455" y="117" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="132" text-anchor="middle">0.75</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="145" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · edit simdjson's documents are read-only: it has no A​PI to change a value and write the result">
|
||||
<rect class="nj-heat-na" x="501" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-tick" x="546" y="138">n/a</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify 1.73× the time of the fastest library (fully validating) way: D​OM + to_string twitter.json: 423 µs citm_catalog.json: 848 µs canada.json: 5,120 µs jeopardy.json: 61,059 µs">
|
||||
<rect class="nj-heat-2" x="593" y="117" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="138" text-anchor="middle">1.73</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify, checking less 0.18× the time of the fastest fully validating library way: minify twitter.json: 62.3 µs citm_catalog.json: 171 µs canada.json: 227 µs jeopardy.json: 5,762 µs simdjson::minify() only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="117" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="132" text-anchor="middle">0.18</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="145" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · write 2.41× the time of the fastest library (fully validating) way: to_string twitter.json: 199 µs citm_catalog.json: 385 µs canada.json: 3,241 µs jeopardy.json: 32,208 µs">
|
||||
<rect class="nj-heat-2" x="685" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="138" text-anchor="middle">2.41</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="174" text-anchor="end">sonic-rs (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · validate 1.93× the time of the fastest library (fully validating) way: Value twitter.json: 326 µs citm_catalog.json: 681 µs canada.json: 1,939 µs jeopardy.json: 31,450 µs">
|
||||
<rect class="nj-heat-2" x="225" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="174" text-anchor="middle">1.93</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · sum 1.53× the time of the fastest library (fully validating) way: visitor twitter.json: 364 µs citm_catalog.json: 778 µs canada.json: 2,703 µs jeopardy.json: 41,361 µs">
|
||||
<rect class="nj-heat-2" x="317" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="174" text-anchor="middle">1.53</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · select 1.83× the time of the fastest library (fully validating) way: Value twitter.json: 333 µs citm_catalog.json: 691 µs canada.json: 1,936 µs jeopardy.json: 40,660 µs">
|
||||
<rect class="nj-heat-2" x="409" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="174" text-anchor="middle">1.83</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · edit 2.08× the time of the fastest library (fully validating) way: Value twitter.json: 634 µs citm_catalog.json: 1,257 µs canada.json: 4,396 µs jeopardy.json: 140,936 µs">
|
||||
<rect class="nj-heat-2" x="501" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="174" text-anchor="middle">2.08</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · minify 1.93× the time of the fastest library (fully validating) way: Value twitter.json: 535 µs citm_catalog.json: 1,134 µs canada.json: 4,377 µs jeopardy.json: 64,832 µs">
|
||||
<rect class="nj-heat-2" x="593" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="174" text-anchor="middle">1.93</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · write 2.38× the time of the fastest library (fully validating) way: Value twitter.json: 212 µs citm_catalog.json: 446 µs canada.json: 2,419 µs jeopardy.json: 33,366 µs">
|
||||
<rect class="nj-heat-2" x="685" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="174" text-anchor="middle">2.38</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="210" text-anchor="end">sonic-cpp</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · validate, checking less 2.53× the time of the fastest fully validating library way: Document twitter.json: 382 µs citm_catalog.json: 985 µs canada.json: 2,578 µs jeopardy.json: 41,617 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-3" x="225" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="204" text-anchor="middle">2.53</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="270" y="217" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · sum, checking less 1.86× the time of the fastest fully validating library way: Document twitter.json: 428 µs citm_catalog.json: 1,087 µs canada.json: 2,993 µs jeopardy.json: 48,688 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="317" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="204" text-anchor="middle">1.86</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="362" y="217" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · select, checking less 2.31× the time of the fastest fully validating library way: Document twitter.json: 385 µs citm_catalog.json: 990 µs canada.json: 2,586 µs jeopardy.json: 45,858 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="409" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="204" text-anchor="middle">2.31</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="454" y="217" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · edit, checking less 1.68× the time of the fastest fully validating library way: Document twitter.json: 486 µs citm_catalog.json: 1,224 µs canada.json: 5,638 µs jeopardy.json: 62,688 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="501" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="204" text-anchor="middle">1.68</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="546" y="217" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · minify, checking less 2.03× the time of the fastest fully validating library way: Document + Serialize twitter.json: 500 µs citm_catalog.json: 1,220 µs canada.json: 5,676 µs jeopardy.json: 61,236 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="593" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="204" text-anchor="middle">2.03</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="638" y="217" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · write 1.59× the time of the fastest library (fully validating) way: Serialize twitter.json: 108 µs citm_catalog.json: 230 µs canada.json: 3,093 µs jeopardy.json: 19,651 µs">
|
||||
<rect class="nj-heat-2" x="685" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="210" text-anchor="middle">1.59</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="246" text-anchor="end">simd-json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · validate 2.07× the time of the fastest library (fully validating) way: tape (copy) twitter.json: 289 µs citm_catalog.json: 698 µs canada.json: 2,278 µs jeopardy.json: 38,874 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-2" x="225" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="246" text-anchor="middle">2.07</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · sum 1.62× the time of the fastest library (fully validating) way: visitor (copy) twitter.json: 354 µs citm_catalog.json: 866 µs canada.json: 2,717 µs jeopardy.json: 47,518 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-2" x="317" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="246" text-anchor="middle">1.62</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · select 2.38× the time of the fastest library (fully validating) way: structs (copy) twitter.json: 364 µs citm_catalog.json: 914 µs canada.json: 2,657 µs jeopardy.json: 57,697 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-2" x="409" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="246" text-anchor="middle">2.38</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · edit 2.84× the time of the fastest library (fully validating) way: borrowed (copy) twitter.json: 948 µs citm_catalog.json: 2,102 µs canada.json: 7,654 µs jeopardy.json: 110,693 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="501" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="246" text-anchor="middle">2.84</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · minify 3.40× the time of the fastest library (fully validating) way: borrowed (copy) twitter.json: 952 µs citm_catalog.json: 2,111 µs canada.json: 7,658 µs jeopardy.json: 108,130 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="593" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="246" text-anchor="middle">3.40</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · write 3.10× the time of the fastest library (fully validating) way: borrowed twitter.json: 355 µs citm_catalog.json: 478 µs canada.json: 2,728 µs jeopardy.json: 47,412 µs">
|
||||
<rect class="nj-heat-3" x="685" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="246" text-anchor="middle">3.10</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="282" text-anchor="end">Glaze</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · validate 2.04× the time of the fastest library (fully validating) way: validate_json twitter.json: 331 µs citm_catalog.json: 862 µs canada.json: 1,326 µs jeopardy.json: 45,192 µs">
|
||||
<rect class="nj-heat-2" x="225" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="282" text-anchor="middle">2.04</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · sum 3.85× the time of the fastest library (fully validating) way: generic (double, strict) twitter.json: 968 µs citm_catalog.json: 2,049 µs canada.json: 6,331 µs jeopardy.json: 99,763 µs">
|
||||
<rect class="nj-heat-3" x="317" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="282" text-anchor="middle">3.85</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select 1.79× the time of the fastest library (fully validating) way: structs (validate_skipped) twitter.json: 311 µs citm_catalog.json: 854 µs canada.json: 1,316 µs jeopardy.json: 46,924 µs">
|
||||
<rect class="nj-heat-2" x="409" y="261" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="282" text-anchor="middle">1.79</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select, checking less 0.82× the time of the fastest fully validating library way: structs twitter.json: 241 µs citm_catalog.json: 255 µs canada.json: 313 µs jeopardy.json: 37,578 µs reads into structs and steps over fields it doesn't know without checking them (validate_skipped checks them too)">
|
||||
<rect class="nj-heat-0" x="455" y="261" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="276" text-anchor="middle">0.82</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="289" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · edit 4.41× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 1,539 µs citm_catalog.json: 3,235 µs canada.json: 11,083 µs jeopardy.json: 178,333 µs">
|
||||
<rect class="nj-heat-3" x="501" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="282" text-anchor="middle">4.41</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify 5.19× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 1,505 µs citm_catalog.json: 3,225 µs canada.json: 11,092 µs jeopardy.json: 168,855 µs">
|
||||
<rect class="nj-heat-4" x="593" y="261" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="282" text-anchor="middle">5.19</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify, checking less 1.03× the time of the fastest fully validating library way: minify_json twitter.json: 281 µs citm_catalog.json: 729 µs canada.json: 1,722 µs jeopardy.json: 39,976 µs minify_json only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="261" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="276" text-anchor="middle">1.03</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="289" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · write 2.23× the time of the fastest library (fully validating) twitter.json: 216 µs · generic citm_catalog.json: 469 µs · generic canada.json: 1,720 µs · generic (strict) jeopardy.json: 33,934 µs · generic">
|
||||
<rect class="nj-heat-2" x="685" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="282" text-anchor="middle">2.23</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="318" text-anchor="end">Boost.J​SON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · validate 2.56× the time of the fastest library (fully validating) way: S​AX (numbers: none) twitter.json: 535 µs citm_catalog.json: 994 µs canada.json: 1,467 µs jeopardy.json: 53,939 µs">
|
||||
<rect class="nj-heat-3" x="225" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="318" text-anchor="middle">2.56</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · sum 1.99× the time of the fastest library (fully validating) way: S​AX twitter.json: 535 µs citm_catalog.json: 1,010 µs canada.json: 3,067 µs jeopardy.json: 53,704 µs">
|
||||
<rect class="nj-heat-2" x="317" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="318" text-anchor="middle">1.99</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · select 3.27× the time of the fastest library (fully validating) twitter.json: 617 µs · parse_into structs citm_catalog.json: 1,205 µs · parse_into structs canada.json: 3,650 µs · parse jeopardy.json: 67,255 µs · parse_into structs">
|
||||
<rect class="nj-heat-3" x="409" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="318" text-anchor="middle">3.27</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · edit 3.21× the time of the fastest library (fully validating) way: parse twitter.json: 1,368 µs citm_catalog.json: 1,992 µs canada.json: 6,573 µs jeopardy.json: 155,237 µs">
|
||||
<rect class="nj-heat-3" x="501" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="318" text-anchor="middle">3.21</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · minify 3.87× the time of the fastest library (fully validating) way: parse + serialize twitter.json: 1,393 µs citm_catalog.json: 1,986 µs canada.json: 6,542 µs jeopardy.json: 154,677 µs">
|
||||
<rect class="nj-heat-3" x="593" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="318" text-anchor="middle">3.87</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · write 3.75× the time of the fastest library (fully validating) way: serialize twitter.json: 507 µs citm_catalog.json: 508 µs canada.json: 2,923 µs jeopardy.json: 62,583 µs">
|
||||
<rect class="nj-heat-3" x="685" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="318" text-anchor="middle">3.75</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="354" text-anchor="end">serde_json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate 2.46× the time of the fastest library (fully validating) way: from_utf8 + IgnoredAny twitter.json: 452 µs citm_catalog.json: 1,103 µs canada.json: 1,556 µs jeopardy.json: 46,517 µs">
|
||||
<rect class="nj-heat-2" x="225" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="354" text-anchor="middle">2.46</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate, checking less 2.23× the time of the fastest fully validating library way: IgnoredAny twitter.json: 354 µs citm_catalog.json: 1,047 µs canada.json: 1,451 µs jeopardy.json: 44,984 µs trusts U​TF-8 in the strings it skips (from_slice); strings it reads are checked">
|
||||
<rect class="nj-heat-2" x="271" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="348" text-anchor="middle">2.23</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="361" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · sum 2.59× the time of the fastest library (fully validating) way: visitor twitter.json: 652 µs citm_catalog.json: 1,242 µs canada.json: 4,772 µs jeopardy.json: 66,568 µs">
|
||||
<rect class="nj-heat-3" x="317" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="354" text-anchor="middle">2.59</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · select 2.39× the time of the fastest library (fully validating) way: from_utf8 + structs twitter.json: 480 µs citm_catalog.json: 1,125 µs canada.json: 1,560 µs jeopardy.json: 62,378 µs">
|
||||
<rect class="nj-heat-2" x="409" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="354" text-anchor="middle">2.39</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · select, checking less 2.24× the time of the fastest fully validating library twitter.json: 410 µs · structs citm_catalog.json: 1,084 µs · structs canada.json: 1,455 µs · structs jeopardy.json: 62,378 µs · from_utf8 + structs (validates fully) trusts U​TF-8 in the strings it skips (from_slice); strings it reads are checked">
|
||||
<rect class="nj-heat-2" x="455" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="348" text-anchor="middle">2.24</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="361" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · edit 4.99× the time of the fastest library (fully validating) way: Value twitter.json: 2,009 µs citm_catalog.json: 3,316 µs canada.json: 9,666 µs jeopardy.json: 251,931 µs">
|
||||
<rect class="nj-heat-3" x="501" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="354" text-anchor="middle">4.99</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · minify 5.85× the time of the fastest library (fully validating) way: Value twitter.json: 2,004 µs citm_catalog.json: 3,290 µs canada.json: 9,792 µs jeopardy.json: 227,369 µs">
|
||||
<rect class="nj-heat-4" x="593" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="354" text-anchor="middle">5.85</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · write 2.95× the time of the fastest library (fully validating) way: Value twitter.json: 322 µs citm_catalog.json: 490 µs canada.json: 2,286 µs jeopardy.json: 49,967 µs">
|
||||
<rect class="nj-heat-3" x="685" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="354" text-anchor="middle">2.95</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="390" text-anchor="end">nlohmann/json json</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · validate 2.71× the time of the fastest library (fully validating) way: accept twitter.json: 451 µs citm_catalog.json: 888 µs canada.json: 2,405 µs jeopardy.json: 55,286 µs">
|
||||
<rect class="nj-heat-3" x="225" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="390" text-anchor="middle">2.71</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · sum 1.96× the time of the fastest library (fully validating) way: sax twitter.json: 465 µs citm_catalog.json: 925 µs canada.json: 3,072 µs jeopardy.json: 64,089 µs">
|
||||
<rect class="nj-heat-2" x="317" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="390" text-anchor="middle">1.96</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · select 6.87× the time of the fastest library (fully validating) twitter.json: 1,360 µs · structs (from_json) citm_catalog.json: 2,416 µs · parse canada.json: 6,047 µs · structs (from_json) jeopardy.json: 179,533 µs · parse">
|
||||
<rect class="nj-heat-4" x="409" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="390" text-anchor="middle">6.87</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · edit 3.73× the time of the fastest library (fully validating) twitter.json: 1,273 µs · ordered_json citm_catalog.json: 2,344 µs · ordered_json canada.json: 8,334 µs · parse jeopardy.json: 203,232 µs · ordered_json">
|
||||
<rect class="nj-heat-3" x="501" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="390" text-anchor="middle">3.73</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · minify 4.89× the time of the fastest library (fully validating) way: parse + dump twitter.json: 1,600 µs citm_catalog.json: 2,706 µs canada.json: 8,389 µs jeopardy.json: 197,745 µs">
|
||||
<rect class="nj-heat-3" x="593" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="390" text-anchor="middle">4.89</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · write 2.10× the time of the fastest library (fully validating) way: dump twitter.json: 223 µs citm_catalog.json: 287 µs canada.json: 2,276 µs jeopardy.json: 31,825 µs">
|
||||
<rect class="nj-heat-2" x="685" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="390" text-anchor="middle">2.10</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="426" text-anchor="end">RapidJSON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate 4.72× the time of the fastest library (fully validating) twitter.json: 1,307 µs · insitu (copy untimed) citm_catalog.json: 1,397 µs · S​AX (string stream, default precision) canada.json: 1,982 µs · S​AX (string stream, default precision) jeopardy.json: 134,679 µs · S​AX (string stream, default precision)">
|
||||
<rect class="nj-heat-3" x="225" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="426" text-anchor="middle">4.72</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate, checking less 3.09× the time of the fastest fully validating library twitter.json: 686 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,032 µs · S​AX (string stream, default precision) (no encoding check) canada.json: 1,982 µs · S​AX (string stream, default precision) (validates fully) jeopardy.json: 63,589 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="271" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="420" text-anchor="middle">3.09</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum 4.15× the time of the fastest library (fully validating) twitter.json: 1,329 µs · S​AX citm_catalog.json: 1,455 µs · S​AX (string stream) canada.json: 6,453 µs · S​AX (string stream) jeopardy.json: 136,103 µs · S​AX (string stream)">
|
||||
<rect class="nj-heat-3" x="317" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="339.5" y="426" text-anchor="middle">4.15</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum, checking less 2.85× the time of the fastest fully validating library twitter.json: 735 µs · S​AX (string stream) (no encoding check) citm_catalog.json: 1,136 µs · S​AX (string stream) (no encoding check) canada.json: 6,453 µs · S​AX (string stream) (validates fully) jeopardy.json: 69,604 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="363" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="384.5" y="420" text-anchor="middle">2.85</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="384.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select 5.91× the time of the fastest library (fully validating) twitter.json: 1,304 µs · insitu (copy untimed) citm_catalog.json: 1,554 µs · insitu (copy untimed) canada.json: 6,776 µs · Document (string stream) jeopardy.json: 141,509 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-4" x="409" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="426" text-anchor="middle">5.91</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select, checking less 3.82× the time of the fastest fully validating library twitter.json: 679 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,126 µs · insitu (copy untimed) (no encoding check) canada.json: 6,776 µs · Document (string stream) (validates fully) jeopardy.json: 65,625 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="455" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="420" text-anchor="middle">3.82</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit 4.82× the time of the fastest library (fully validating) twitter.json: 1,922 µs · Document citm_catalog.json: 2,388 µs · insitu (copy untimed) canada.json: 13,836 µs · Document (string stream) jeopardy.json: 221,270 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="501" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="426" text-anchor="middle">4.82</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit, checking less 3.77× the time of the fastest fully validating library way: insitu (copy untimed) (no encoding check) twitter.json: 1,344 µs citm_catalog.json: 1,964 µs canada.json: 13,794 µs jeopardy.json: 144,741 µs trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="547" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="420" text-anchor="middle">3.77</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify 4.86× the time of the fastest library (fully validating) twitter.json: 1,525 µs · S​AX to Writer citm_catalog.json: 1,808 µs · S​AX to Writer (string stream) canada.json: 14,460 µs · Document + Writer jeopardy.json: 174,558 µs · S​AX to Writer (string stream)">
|
||||
<rect class="nj-heat-3" x="593" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="426" text-anchor="middle">4.86</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify, checking less 3.60× the time of the fastest fully validating library twitter.json: 1,058 µs · S​AX to Writer (string stream) (no encoding check) citm_catalog.json: 1,485 µs · S​AX to Writer (string stream) (no encoding check) canada.json: 10,908 µs · S​AX to Writer (raw numbers) (no encoding check) jeopardy.json: 123,119 µs · S​AX to Writer (string stream) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it) copies each number's text instead of formatting it (kParseNumbersAsStringsFlag)">
|
||||
<rect class="nj-heat-3" x="639" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="420" text-anchor="middle">3.60</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="433" text-anchor="middle">U N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · write 5.88× the time of the fastest library (fully validating) way: Writer twitter.json: 603 µs citm_catalog.json: 830 µs canada.json: 6,995 µs jeopardy.json: 81,150 µs">
|
||||
<rect class="nj-heat-4" x="685" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="426" text-anchor="middle">5.88</text>
|
||||
</g>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="472">time relative to the fastest fully validating library, less is better</text>
|
||||
<g><rect class="nj-heat-0" x="8" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="46" y="496" text-anchor="middle">below 1.15</text></g>
|
||||
<g><rect class="nj-heat-1" x="88" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="126" y="496" text-anchor="middle">1.15 to 1.5</text></g>
|
||||
<g><rect class="nj-heat-2" x="168" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="206" y="496" text-anchor="middle">1.5 to 2.5</text></g>
|
||||
<g><rect class="nj-heat-3" x="248" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="286" y="496" text-anchor="middle">2.5 to 5</text></g>
|
||||
<g><rect class="nj-heat-4" x="328" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="366" y="496" text-anchor="middle">5 and more</text></g>
|
||||
<rect class="nj-heat-na" x="420" y="482" width="40" height="20" rx="3"/>
|
||||
<text class="nj-charts-tick" x="440" y="496">n/a</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="468" y="496">no A​PI for it</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 45 KiB |
@@ -1,379 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog nj-charts--heat" viewBox="0 0 784 510" role="img" aria-labelledby="nj-blog-uc-x86-clang nj-blog-uc-x86-clang-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-uc-x86-clang">Use cases: time of each library relative to the fastest, x86-64 with Clang 23</title>
|
||||
<desc id="nj-blog-uc-x86-clang-d">Table of relative times, libraries by use case. nlohmann/json json_document validate: 1.00; nlohmann/json json_document sum: 1.00; nlohmann/json json_document select: 1.00; nlohmann/json json_document edit: 1.00 (0.81 doing less, N); nlohmann/json json_document minify: 1.00 (0.83 doing less, N); nlohmann/json json_document write: 1.00 (0.69 doing less, N); yyjson validate: 1.87; yyjson sum: 1.00; yyjson select: 1.23; yyjson edit: 1.43; yyjson minify: 1.16 (1.00 doing less, N); yyjson write: 1.14; sonic-cpp validate: no fully validating way (2.32 doing less, U); sonic-cpp sum: no fully validating way (1.20 doing less, U); sonic-cpp select: no fully validating way (1.53 doing less, U); sonic-cpp edit: no fully validating way (1.24 doing less, U); sonic-cpp minify: no fully validating way (1.38 doing less, U); sonic-cpp write: 1.28; simdjson validate: 2.03; simdjson sum: 1.13; simdjson select: 1.32 (0.57 doing less, P); simdjson edit: n/a; simdjson minify: 1.58 (0.18 doing less, P); simdjson write: 2.00; sonic-rs (Rust) validate: 1.88; sonic-rs (Rust) sum: 1.07; sonic-rs (Rust) select: 1.39; sonic-rs (Rust) edit: 1.90; sonic-rs (Rust) minify: 1.73; sonic-rs (Rust) write: 1.94; Boost.J​SON validate: 1.79; Boost.J​SON sum: 1.12; Boost.J​SON select: 2.24; Boost.J​SON edit: 2.39; Boost.J​SON minify: 2.68; Boost.J​SON write: 2.31; simd-json (Rust) validate: 3.52; simd-json (Rust) sum: 1.80; simd-json (Rust) select: 2.64; simd-json (Rust) edit: 2.88; simd-json (Rust) minify: 3.38; simd-json (Rust) write: 2.21; serde_json (Rust) validate: 2.33 (2.08 doing less, U); serde_json (Rust) sum: 2.22; serde_json (Rust) select: 1.77; serde_json (Rust) edit: 4.54; serde_json (Rust) minify: 4.92; serde_json (Rust) write: 2.15; Glaze validate: 2.23; Glaze sum: 4.03 (3.78 doing less, P); Glaze select: 1.43 (0.62 doing less, P); Glaze edit: 5.53; Glaze minify: 5.77 (0.70 doing less, P); Glaze write: 1.90; nlohmann/json json validate: 2.77; nlohmann/json json sum: 1.44; nlohmann/json json select: 7.56; nlohmann/json json edit: 3.99; nlohmann/json json minify: 4.91; nlohmann/json json write: 1.86; RapidJSON validate: 4.94 (3.76 doing less, U); RapidJSON sum: 2.98 (2.28 doing less, U); RapidJSON select: 4.20 (3.27 doing less, U); RapidJSON edit: 3.06 (2.60 doing less, U); RapidJSON minify: 3.61 (2.65 doing less, U N); RapidJSON write: 2.79.</desc>
|
||||
<text class="nj-charts-tick" x="270" y="34">validate</text>
|
||||
<text class="nj-charts-tick" x="362" y="34">sum</text>
|
||||
<text class="nj-charts-tick" x="454" y="34">select</text>
|
||||
<text class="nj-charts-tick" x="546" y="34">edit</text>
|
||||
<text class="nj-charts-tick" x="638" y="34">minify</text>
|
||||
<text class="nj-charts-tick" x="730" y="34">write</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="66" text-anchor="end">nlohmann/json json_document</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · validate 1.00× the time of the fastest library (fully validating) way: accept twitter.json: 255 µs citm_catalog.json: 512 µs canada.json: 1,055 µs jeopardy.json: 34,729 µs">
|
||||
<rect class="nj-heat-0" x="225" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · sum 1.00× the time of the fastest library (fully validating) way: parse twitter.json: 374 µs citm_catalog.json: 923 µs canada.json: 3,846 µs jeopardy.json: 85,286 µs">
|
||||
<rect class="nj-heat-0" x="317" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · select 1.00× the time of the fastest library (fully validating) twitter.json: 320 µs · parse citm_catalog.json: 759 µs · parse canada.json: 1,390 µs · structs (from_json) jeopardy.json: 88,083 µs · parse">
|
||||
<rect class="nj-heat-0" x="409" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit 1.00× the time of the fastest library (fully validating) way: editable twitter.json: 526 µs citm_catalog.json: 1,127 µs canada.json: 5,674 µs jeopardy.json: 196,370 µs">
|
||||
<rect class="nj-heat-0" x="501" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit, checking less 0.81× the time of the fastest fully validating library twitter.json: 526 µs · editable (validates fully) citm_catalog.json: 1,127 µs · editable (validates fully) canada.json: 2,443 µs · editable (source numbers) (validates fully) jeopardy.json: 196,370 µs · editable (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="547" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="60" text-anchor="middle">0.81</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify 1.00× the time of the fastest library (fully validating) way: parse + dump twitter.json: 518 µs citm_catalog.json: 1,040 µs canada.json: 5,043 µs jeopardy.json: 146,125 µs">
|
||||
<rect class="nj-heat-0" x="593" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify, checking less 0.83× the time of the fastest fully validating library twitter.json: 518 µs · parse + dump (validates fully) citm_catalog.json: 1,030 µs · parse + dump (source numbers) (validates fully) canada.json: 2,456 µs · parse + dump (source numbers) (validates fully) jeopardy.json: 146,125 µs · parse + dump (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="639" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="60" text-anchor="middle">0.83</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write 1.00× the time of the fastest library (fully validating) way: dump twitter.json: 160 µs citm_catalog.json: 311 µs canada.json: 3,714 µs jeopardy.json: 67,038 µs">
|
||||
<rect class="nj-heat-0" x="685" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="707.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write, checking less 0.69× the time of the fastest fully validating library way: dump (source numbers) twitter.json: 154 µs (validates fully) citm_catalog.json: 279 µs (validates fully) canada.json: 989 µs (validates fully) jeopardy.json: 64,301 µs (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="731" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="752.5" y="60" text-anchor="middle">0.69</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="752.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="102" text-anchor="end">yyjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · validate 1.87× the time of the fastest library (fully validating) twitter.json: 334 µs · insitu (copy untimed) citm_catalog.json: 811 µs · insitu (copy untimed) canada.json: 2,580 µs · read (raw numbers) jeopardy.json: 83,153 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-2" x="225" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="102" text-anchor="middle">1.87</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · sum 1.00× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 399 µs citm_catalog.json: 946 µs canada.json: 3,445 µs jeopardy.json: 88,447 µs">
|
||||
<rect class="nj-heat-0" x="317" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="102" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · select 1.23× the time of the fastest library (fully validating) twitter.json: 351 µs · insitu (copy untimed) citm_catalog.json: 788 µs · insitu (copy untimed) canada.json: 2,632 µs · read (raw numbers) jeopardy.json: 92,551 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-1" x="409" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="102" text-anchor="middle">1.23</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · edit 1.43× the time of the fastest library (fully validating) twitter.json: 918 µs · insitu (copy) + mut copy citm_catalog.json: 1,548 µs · insitu (copy untimed) + mut copy canada.json: 7,155 µs · insitu (copy untimed) + mut copy jeopardy.json: 270,654 µs · insitu (copy untimed) + mut copy (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-1" x="501" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="102" text-anchor="middle">1.43</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify 1.16× the time of the fastest library (fully validating) way: insitu (copy untimed) + write twitter.json: 620 µs citm_catalog.json: 1,189 µs canada.json: 6,283 µs jeopardy.json: 154,016 µs">
|
||||
<rect class="nj-heat-1" x="593" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="102" text-anchor="middle">1.16</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify, checking less 1.00× the time of the fastest fully validating library twitter.json: 620 µs · insitu (copy untimed) + write (validates fully) citm_catalog.json: 1,189 µs · insitu (copy untimed) + write (validates fully) canada.json: 3,472 µs · read (raw numbers) + write (validates fully) jeopardy.json: 154,016 µs · insitu (copy untimed) + write (validates fully) copies each number's text instead of formatting it (YYJSON_READ_NUMBER_AS_RAW)">
|
||||
<rect class="nj-heat-0" x="639" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="96" text-anchor="middle">1.00</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="109" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · write 1.14× the time of the fastest library (fully validating) way: write twitter.json: 218 µs citm_catalog.json: 386 µs canada.json: 3,476 µs jeopardy.json: 71,247 µs">
|
||||
<rect class="nj-heat-0" x="685" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="102" text-anchor="middle">1.14</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="138" text-anchor="end">sonic-cpp</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · validate, checking less 2.32× the time of the fastest fully validating library way: Document twitter.json: 448 µs citm_catalog.json: 1,032 µs canada.json: 3,143 µs jeopardy.json: 94,884 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="225" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="132" text-anchor="middle">2.32</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="270" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · sum, checking less 1.20× the time of the fastest fully validating library way: Document twitter.json: 502 µs citm_catalog.json: 1,175 µs canada.json: 3,754 µs jeopardy.json: 104,583 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="317" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="132" text-anchor="middle">1.20</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="362" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · select, checking less 1.53× the time of the fastest fully validating library way: Document twitter.json: 460 µs citm_catalog.json: 1,011 µs canada.json: 3,204 µs jeopardy.json: 108,245 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="409" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="132" text-anchor="middle">1.53</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="454" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · edit, checking less 1.24× the time of the fastest fully validating library way: Document twitter.json: 711 µs citm_catalog.json: 1,472 µs canada.json: 7,996 µs jeopardy.json: 183,852 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="501" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="132" text-anchor="middle">1.24</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="546" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · minify, checking less 1.38× the time of the fastest fully validating library way: Document + Serialize twitter.json: 710 µs citm_catalog.json: 1,485 µs canada.json: 8,122 µs jeopardy.json: 166,935 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="593" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="132" text-anchor="middle">1.38</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="638" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · write 1.28× the time of the fastest library (fully validating) way: Serialize twitter.json: 224 µs citm_catalog.json: 475 µs canada.json: 4,850 µs jeopardy.json: 65,131 µs">
|
||||
<rect class="nj-heat-1" x="685" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="138" text-anchor="middle">1.28</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="174" text-anchor="end">simdjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · validate 2.03× the time of the fastest library (fully validating) way: D​OM twitter.json: 306 µs citm_catalog.json: 732 µs canada.json: 3,206 µs jeopardy.json: 113,452 µs">
|
||||
<rect class="nj-heat-2" x="225" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="174" text-anchor="middle">2.03</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · sum 1.13× the time of the fastest library (fully validating) twitter.json: 394 µs · D​OM citm_catalog.json: 977 µs · D​OM canada.json: 4,117 µs · D​OM jeopardy.json: 114,602 µs · On-Demand">
|
||||
<rect class="nj-heat-0" x="317" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="174" text-anchor="middle">1.13</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select 1.32× the time of the fastest library (fully validating) way: D​OM twitter.json: 316 µs citm_catalog.json: 731 µs canada.json: 3,262 µs jeopardy.json: 120,808 µs">
|
||||
<rect class="nj-heat-1" x="409" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="174" text-anchor="middle">1.32</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select, checking less 0.57× the time of the fastest fully validating library twitter.json: 181 µs · On-Demand structs citm_catalog.json: 495 µs · On-Demand canada.json: 702 µs · On-Demand jeopardy.json: 48,823 µs · On-Demand reads lazily: On-Demand reads only what you ask for and steps over the rest by matching brackets">
|
||||
<rect class="nj-heat-0" x="455" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="168" text-anchor="middle">0.57</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="181" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · edit simdjson's documents are read-only: it has no A​PI to change a value and write the result">
|
||||
<rect class="nj-heat-na" x="501" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-tick" x="546" y="174">n/a</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify 1.58× the time of the fastest library (fully validating) way: D​OM + to_string twitter.json: 783 µs citm_catalog.json: 1,395 µs canada.json: 8,303 µs jeopardy.json: 275,007 µs">
|
||||
<rect class="nj-heat-2" x="593" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="174" text-anchor="middle">1.58</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify, checking less 0.18× the time of the fastest fully validating library way: minify twitter.json: 105 µs citm_catalog.json: 269 µs canada.json: 337 µs jeopardy.json: 45,087 µs simdjson::minify() only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="168" text-anchor="middle">0.18</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="181" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · write 2.00× the time of the fastest library (fully validating) way: to_string twitter.json: 389 µs citm_catalog.json: 656 µs canada.json: 4,896 µs jeopardy.json: 157,616 µs">
|
||||
<rect class="nj-heat-2" x="685" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="174" text-anchor="middle">2.00</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="210" text-anchor="end">sonic-rs (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · validate 1.88× the time of the fastest library (fully validating) way: IgnoredAny twitter.json: 501 µs citm_catalog.json: 970 µs canada.json: 2,249 µs jeopardy.json: 54,369 µs">
|
||||
<rect class="nj-heat-2" x="225" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="210" text-anchor="middle">1.88</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · sum 1.07× the time of the fastest library (fully validating) way: visitor twitter.json: 501 µs citm_catalog.json: 1,123 µs canada.json: 4,397 µs jeopardy.json: 59,583 µs">
|
||||
<rect class="nj-heat-0" x="317" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="210" text-anchor="middle">1.07</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · select 1.39× the time of the fastest library (fully validating) way: structs twitter.json: 504 µs citm_catalog.json: 1,033 µs canada.json: 2,328 µs jeopardy.json: 90,486 µs">
|
||||
<rect class="nj-heat-1" x="409" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="210" text-anchor="middle">1.39</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · edit 1.90× the time of the fastest library (fully validating) way: Value twitter.json: 1,197 µs citm_catalog.json: 2,389 µs canada.json: 7,744 µs jeopardy.json: 390,952 µs">
|
||||
<rect class="nj-heat-2" x="501" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="210" text-anchor="middle">1.90</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · minify 1.73× the time of the fastest library (fully validating) way: Value twitter.json: 1,000 µs citm_catalog.json: 2,097 µs canada.json: 7,795 µs jeopardy.json: 215,280 µs">
|
||||
<rect class="nj-heat-2" x="593" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="210" text-anchor="middle">1.73</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · write 1.94× the time of the fastest library (fully validating) way: Value twitter.json: 434 µs citm_catalog.json: 927 µs canada.json: 3,987 µs jeopardy.json: 109,176 µs">
|
||||
<rect class="nj-heat-2" x="685" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="210" text-anchor="middle">1.94</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="246" text-anchor="end">Boost.J​SON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · validate 1.79× the time of the fastest library (fully validating) way: S​AX (numbers: none) twitter.json: 571 µs citm_catalog.json: 910 µs canada.json: 1,684 µs jeopardy.json: 55,498 µs">
|
||||
<rect class="nj-heat-2" x="225" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="246" text-anchor="middle">1.79</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · sum 1.12× the time of the fastest library (fully validating) way: S​AX twitter.json: 580 µs citm_catalog.json: 928 µs canada.json: 5,809 µs jeopardy.json: 56,774 µs">
|
||||
<rect class="nj-heat-0" x="317" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="246" text-anchor="middle">1.12</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · select 2.24× the time of the fastest library (fully validating) twitter.json: 776 µs · parse_into structs citm_catalog.json: 1,389 µs · parse_into structs canada.json: 7,121 µs · parse jeopardy.json: 97,681 µs · parse_into structs">
|
||||
<rect class="nj-heat-2" x="409" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="246" text-anchor="middle">2.24</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · edit 2.39× the time of the fastest library (fully validating) way: parse twitter.json: 1,855 µs citm_catalog.json: 2,596 µs canada.json: 12,765 µs jeopardy.json: 350,286 µs">
|
||||
<rect class="nj-heat-2" x="501" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="246" text-anchor="middle">2.39</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · minify 2.68× the time of the fastest library (fully validating) way: parse + serialize twitter.json: 1,924 µs citm_catalog.json: 2,569 µs canada.json: 12,622 µs jeopardy.json: 329,090 µs">
|
||||
<rect class="nj-heat-3" x="593" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="246" text-anchor="middle">2.68</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · write 2.31× the time of the fastest library (fully validating) way: serialize twitter.json: 478 µs citm_catalog.json: 916 µs canada.json: 5,615 µs jeopardy.json: 141,846 µs">
|
||||
<rect class="nj-heat-2" x="685" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="246" text-anchor="middle">2.31</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="282" text-anchor="end">simd-json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · validate 3.52× the time of the fastest library (fully validating) way: tape (copy) twitter.json: 567 µs citm_catalog.json: 1,430 µs canada.json: 4,359 µs jeopardy.json: 207,551 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="225" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="282" text-anchor="middle">3.52</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · sum 1.80× the time of the fastest library (fully validating) way: visitor (copy) twitter.json: 681 µs citm_catalog.json: 1,650 µs canada.json: 5,083 µs jeopardy.json: 210,185 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-2" x="317" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="282" text-anchor="middle">1.80</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · select 2.64× the time of the fastest library (fully validating) way: structs (copy) twitter.json: 679 µs citm_catalog.json: 1,731 µs canada.json: 5,144 µs jeopardy.json: 239,164 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="409" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="282" text-anchor="middle">2.64</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · edit 2.88× the time of the fastest library (fully validating) twitter.json: 1,862 µs · borrowed (copy) citm_catalog.json: 4,194 µs · borrowed (copy) canada.json: 14,896 µs · owned (copy) jeopardy.json: 391,369 µs · borrowed (copy) (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="501" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="282" text-anchor="middle">2.88</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · minify 3.38× the time of the fastest library (fully validating) way: borrowed (copy) twitter.json: 1,889 µs citm_catalog.json: 4,196 µs canada.json: 15,716 µs jeopardy.json: 414,377 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="593" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="282" text-anchor="middle">3.38</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · write 2.21× the time of the fastest library (fully validating) way: borrowed twitter.json: 582 µs citm_catalog.json: 800 µs canada.json: 5,147 µs jeopardy.json: 122,623 µs">
|
||||
<rect class="nj-heat-2" x="685" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="282" text-anchor="middle">2.21</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="318" text-anchor="end">serde_json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate 2.33× the time of the fastest library (fully validating) way: from_utf8 + IgnoredAny twitter.json: 624 µs citm_catalog.json: 1,440 µs canada.json: 2,406 µs jeopardy.json: 64,720 µs">
|
||||
<rect class="nj-heat-2" x="225" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="318" text-anchor="middle">2.33</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate, checking less 2.08× the time of the fastest fully validating library way: IgnoredAny twitter.json: 484 µs citm_catalog.json: 1,370 µs canada.json: 2,314 µs jeopardy.json: 58,247 µs trusts U​TF-8 in the strings it skips (from_slice); strings it reads are checked">
|
||||
<rect class="nj-heat-2" x="271" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="312" text-anchor="middle">2.08</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="325" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · sum 2.22× the time of the fastest library (fully validating) way: visitor twitter.json: 1,311 µs citm_catalog.json: 2,288 µs canada.json: 7,127 µs jeopardy.json: 129,497 µs">
|
||||
<rect class="nj-heat-2" x="317" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="318" text-anchor="middle">2.22</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · select 1.77× the time of the fastest library (fully validating) way: from_utf8 + structs twitter.json: 701 µs citm_catalog.json: 1,532 µs canada.json: 2,529 µs jeopardy.json: 107,316 µs">
|
||||
<rect class="nj-heat-2" x="409" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="318" text-anchor="middle">1.77</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · edit 4.54× the time of the fastest library (fully validating) way: Value twitter.json: 4,042 µs citm_catalog.json: 6,586 µs canada.json: 16,631 µs jeopardy.json: 632,766 µs">
|
||||
<rect class="nj-heat-3" x="501" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="318" text-anchor="middle">4.54</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · minify 4.92× the time of the fastest library (fully validating) way: Value twitter.json: 4,012 µs citm_catalog.json: 6,583 µs canada.json: 17,306 µs jeopardy.json: 509,702 µs">
|
||||
<rect class="nj-heat-3" x="593" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="318" text-anchor="middle">4.92</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · write 2.15× the time of the fastest library (fully validating) way: Value twitter.json: 550 µs citm_catalog.json: 887 µs canada.json: 4,005 µs jeopardy.json: 134,163 µs">
|
||||
<rect class="nj-heat-2" x="685" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="318" text-anchor="middle">2.15</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="354" text-anchor="end">Glaze</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · validate 2.23× the time of the fastest library (fully validating) way: validate_json twitter.json: 588 µs citm_catalog.json: 1,431 µs canada.json: 1,867 µs jeopardy.json: 75,571 µs">
|
||||
<rect class="nj-heat-2" x="225" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="354" text-anchor="middle">2.23</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · sum 4.03× the time of the fastest library (fully validating) way: generic (double, strict) twitter.json: 2,427 µs citm_catalog.json: 3,972 µs canada.json: 12,165 µs jeopardy.json: 253,385 µs">
|
||||
<rect class="nj-heat-3" x="317" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="339.5" y="354" text-anchor="middle">4.03</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · sum, checking less 3.78× the time of the fastest fully validating library twitter.json: 2,427 µs · generic (double, strict) (validates fully) citm_catalog.json: 3,972 µs · generic (double, strict) (validates fully) canada.json: 12,165 µs · generic (double, strict) (validates fully) jeopardy.json: 196,582 µs · lazy_json reads lazily: lazy_json reads only what you ask for and steps over the rest">
|
||||
<rect class="nj-heat-3" x="363" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="384.5" y="348" text-anchor="middle">3.78</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="384.5" y="361" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select 1.43× the time of the fastest library (fully validating) way: structs (validate_skipped) twitter.json: 544 µs citm_catalog.json: 1,368 µs canada.json: 1,924 µs jeopardy.json: 85,745 µs">
|
||||
<rect class="nj-heat-1" x="409" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="354" text-anchor="middle">1.43</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select, checking less 0.62× the time of the fastest fully validating library way: structs twitter.json: 345 µs citm_catalog.json: 419 µs canada.json: 444 µs jeopardy.json: 66,442 µs reads into structs and steps over fields it doesn't know without checking them (validate_skipped checks them too)">
|
||||
<rect class="nj-heat-0" x="455" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="348" text-anchor="middle">0.62</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="361" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · edit 5.53× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 4,341 µs citm_catalog.json: 7,322 µs canada.json: 26,786 µs jeopardy.json: 725,881 µs">
|
||||
<rect class="nj-heat-4" x="501" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="354" text-anchor="middle">5.53</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify 5.77× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 4,132 µs citm_catalog.json: 7,465 µs canada.json: 26,962 µs jeopardy.json: 528,811 µs">
|
||||
<rect class="nj-heat-4" x="593" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="354" text-anchor="middle">5.77</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify, checking less 0.70× the time of the fastest fully validating library way: minify_json twitter.json: 444 µs citm_catalog.json: 1,059 µs canada.json: 2,222 µs jeopardy.json: 91,153 µs minify_json only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="348" text-anchor="middle">0.70</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="361" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · write 1.90× the time of the fastest library (fully validating) way: generic twitter.json: 399 µs citm_catalog.json: 748 µs canada.json: 4,220 µs jeopardy.json: 128,020 µs">
|
||||
<rect class="nj-heat-2" x="685" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="354" text-anchor="middle">1.90</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="390" text-anchor="end">nlohmann/json json</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · validate 2.77× the time of the fastest library (fully validating) way: accept twitter.json: 658 µs citm_catalog.json: 1,390 µs canada.json: 4,265 µs jeopardy.json: 71,982 µs">
|
||||
<rect class="nj-heat-3" x="225" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="390" text-anchor="middle">2.77</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · sum 1.44× the time of the fastest library (fully validating) way: sax twitter.json: 728 µs citm_catalog.json: 1,393 µs canada.json: 5,428 µs jeopardy.json: 89,481 µs">
|
||||
<rect class="nj-heat-1" x="317" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="390" text-anchor="middle">1.44</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · select 7.56× the time of the fastest library (fully validating) twitter.json: 3,602 µs · structs (from_json) citm_catalog.json: 5,124 µs · parse canada.json: 11,831 µs · parse jeopardy.json: 444,210 µs · parse">
|
||||
<rect class="nj-heat-4" x="409" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="390" text-anchor="middle">7.56</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · edit 3.99× the time of the fastest library (fully validating) twitter.json: 3,069 µs · ordered_json citm_catalog.json: 4,905 µs · ordered_json canada.json: 16,702 µs · parse jeopardy.json: 666,261 µs · ordered_json">
|
||||
<rect class="nj-heat-3" x="501" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="390" text-anchor="middle">3.99</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · minify 4.91× the time of the fastest library (fully validating) way: parse + dump twitter.json: 4,445 µs citm_catalog.json: 5,713 µs canada.json: 16,711 µs jeopardy.json: 543,033 µs">
|
||||
<rect class="nj-heat-3" x="593" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="390" text-anchor="middle">4.91</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · write 1.86× the time of the fastest library (fully validating) way: dump twitter.json: 451 µs citm_catalog.json: 628 µs canada.json: 4,506 µs jeopardy.json: 116,529 µs">
|
||||
<rect class="nj-heat-2" x="685" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="390" text-anchor="middle">1.86</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="426" text-anchor="end">RapidJSON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate 4.94× the time of the fastest library (fully validating) twitter.json: 1,756 µs · insitu (copy untimed) citm_catalog.json: 1,971 µs · S​AX (default precision) canada.json: 4,118 µs · S​AX (string stream, default precision) jeopardy.json: 198,915 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="225" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="426" text-anchor="middle">4.94</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate, checking less 3.76× the time of the fastest fully validating library twitter.json: 1,132 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,572 µs · S​AX (default precision) (no encoding check) canada.json: 4,083 µs · S​AX (string stream, default precision) (no encoding check) jeopardy.json: 131,204 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="271" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="420" text-anchor="middle">3.76</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum 2.98× the time of the fastest library (fully validating) twitter.json: 1,816 µs · insitu (copy untimed) citm_catalog.json: 2,224 µs · S​AX canada.json: 10,719 µs · S​AX (string stream) jeopardy.json: 206,811 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="317" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="339.5" y="426" text-anchor="middle">2.98</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum, checking less 2.28× the time of the fastest fully validating library twitter.json: 1,187 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,765 µs · S​AX (no encoding check) canada.json: 10,719 µs · S​AX (string stream) (validates fully) jeopardy.json: 135,945 µs · S​AX (string stream) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-2" x="363" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="384.5" y="420" text-anchor="middle">2.28</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="384.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select 4.20× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 1,762 µs citm_catalog.json: 2,198 µs canada.json: 11,464 µs jeopardy.json: 209,290 µs">
|
||||
<rect class="nj-heat-3" x="409" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="426" text-anchor="middle">4.20</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select, checking less 3.27× the time of the fastest fully validating library twitter.json: 1,144 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,817 µs · insitu (copy untimed) (no encoding check) canada.json: 11,464 µs · insitu (copy untimed) (validates fully) jeopardy.json: 142,852 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="455" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="420" text-anchor="middle">3.27</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit 3.06× the time of the fastest library (fully validating) twitter.json: 2,635 µs · insitu (copy) citm_catalog.json: 3,103 µs · insitu (copy untimed) canada.json: 21,139 µs · insitu (copy untimed) jeopardy.json: 333,913 µs · insitu (copy untimed) (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="501" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="426" text-anchor="middle">3.06</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit, checking less 2.60× the time of the fastest fully validating library twitter.json: 1,952 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 2,728 µs · insitu (copy untimed) (no encoding check) canada.json: 21,139 µs · insitu (copy untimed) (validates fully) jeopardy.json: 267,081 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="547" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="420" text-anchor="middle">2.60</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify 3.61× the time of the fastest library (fully validating) twitter.json: 2,808 µs · S​AX to Writer citm_catalog.json: 2,975 µs · S​AX to Writer canada.json: 22,589 µs · Document + Writer jeopardy.json: 358,807 µs · S​AX to Writer (string stream)">
|
||||
<rect class="nj-heat-3" x="593" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="426" text-anchor="middle">3.61</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify, checking less 2.65× the time of the fastest fully validating library twitter.json: 2,022 µs · S​AX to Writer (raw numbers) (no encoding check) citm_catalog.json: 2,480 µs · S​AX to Writer (no encoding check) canada.json: 14,986 µs · S​AX to Writer (raw numbers) (validates fully) jeopardy.json: 261,527 µs · S​AX to Writer (string stream) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it) copies each number's text instead of formatting it (kParseNumbersAsStringsFlag)">
|
||||
<rect class="nj-heat-3" x="639" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="420" text-anchor="middle">2.65</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="433" text-anchor="middle">U N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · write 2.79× the time of the fastest library (fully validating) way: Writer twitter.json: 627 µs citm_catalog.json: 1,008 µs canada.json: 9,596 µs jeopardy.json: 123,764 µs">
|
||||
<rect class="nj-heat-3" x="685" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="426" text-anchor="middle">2.79</text>
|
||||
</g>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="472">time relative to the fastest fully validating library, less is better</text>
|
||||
<g><rect class="nj-heat-0" x="8" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="46" y="496" text-anchor="middle">below 1.15</text></g>
|
||||
<g><rect class="nj-heat-1" x="88" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="126" y="496" text-anchor="middle">1.15 to 1.5</text></g>
|
||||
<g><rect class="nj-heat-2" x="168" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="206" y="496" text-anchor="middle">1.5 to 2.5</text></g>
|
||||
<g><rect class="nj-heat-3" x="248" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="286" y="496" text-anchor="middle">2.5 to 5</text></g>
|
||||
<g><rect class="nj-heat-4" x="328" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="366" y="496" text-anchor="middle">5 and more</text></g>
|
||||
<rect class="nj-heat-na" x="420" y="482" width="40" height="20" rx="3"/>
|
||||
<text class="nj-charts-tick" x="440" y="496">n/a</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="468" y="496">no A​PI for it</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 46 KiB |
@@ -1,374 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog nj-charts--heat" viewBox="0 0 784 510" role="img" aria-labelledby="nj-blog-uc-x86-gcc nj-blog-uc-x86-gcc-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-uc-x86-gcc">Use cases: time of each library relative to the fastest, x86-64 with G​CC 16.2</title>
|
||||
<desc id="nj-blog-uc-x86-gcc-d">Table of relative times, libraries by use case. nlohmann/json json_document validate: 1.00; nlohmann/json json_document sum: 1.08; nlohmann/json json_document select: 1.00; nlohmann/json json_document edit: 1.00 (0.79 doing less, N); nlohmann/json json_document minify: 1.00 (0.80 doing less, N); nlohmann/json json_document write: 1.00 (0.64 doing less, N); yyjson validate: 1.94; yyjson sum: 1.14; yyjson select: 1.18; yyjson edit: 1.37; yyjson minify: 1.17 (0.95 doing less, N); yyjson write: 1.11; sonic-cpp validate: no fully validating way (2.32 doing less, U); sonic-cpp sum: no fully validating way (1.24 doing less, U); sonic-cpp select: no fully validating way (1.45 doing less, U); sonic-cpp edit: no fully validating way (1.21 doing less, U); sonic-cpp minify: no fully validating way (1.36 doing less, U); sonic-cpp write: 1.45; simdjson validate: 2.11; simdjson sum: 1.00; simdjson select: 1.27 (0.54 doing less, P); simdjson edit: n/a; simdjson minify: 1.54 (0.17 doing less, P); simdjson write: 2.10; sonic-rs (Rust) validate: 1.93; sonic-rs (Rust) sum: 1.13; sonic-rs (Rust) select: 1.34; sonic-rs (Rust) edit: 1.90; sonic-rs (Rust) minify: 1.71; sonic-rs (Rust) write: 2.04; Boost.J​SON validate: 1.99; Boost.J​SON sum: 1.27; Boost.J​SON select: 2.20; Boost.J​SON edit: 2.30; Boost.J​SON minify: 2.65; Boost.J​SON write: 2.36; simd-json (Rust) validate: 3.62; simd-json (Rust) sum: 1.91; simd-json (Rust) select: 2.56; simd-json (Rust) edit: 2.87; simd-json (Rust) minify: 3.35; simd-json (Rust) write: 2.32; RapidJSON validate: 3.71 (3.41 doing less, U); RapidJSON sum: 2.23 (2.09 doing less, U); RapidJSON select: 2.91 (2.73 doing less, U); RapidJSON edit: 2.41 (2.34 doing less, U); RapidJSON minify: 2.68 (2.42 doing less, U N); RapidJSON write: 2.97; serde_json (Rust) validate: 2.39 (2.14 doing less, U); serde_json (Rust) sum: 2.36; serde_json (Rust) select: 1.71; serde_json (Rust) edit: 4.53; serde_json (Rust) minify: 4.89; serde_json (Rust) write: 2.25; Glaze validate: 2.86; Glaze sum: 4.16; Glaze select: 1.79 (0.58 doing less, P); Glaze edit: 4.47; Glaze minify: 4.81 (0.78 doing less, P); Glaze write: 1.96; nlohmann/json json validate: 2.96; nlohmann/json json sum: 1.70; nlohmann/json json select: 7.12; nlohmann/json json edit: 3.83; nlohmann/json json minify: 4.79; nlohmann/json json write: 1.91.</desc>
|
||||
<text class="nj-charts-tick" x="270" y="34">validate</text>
|
||||
<text class="nj-charts-tick" x="362" y="34">sum</text>
|
||||
<text class="nj-charts-tick" x="454" y="34">select</text>
|
||||
<text class="nj-charts-tick" x="546" y="34">edit</text>
|
||||
<text class="nj-charts-tick" x="638" y="34">minify</text>
|
||||
<text class="nj-charts-tick" x="730" y="34">write</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="66" text-anchor="end">nlohmann/json json_document</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · validate 1.00× the time of the fastest library (fully validating) way: accept twitter.json: 258 µs citm_catalog.json: 513 µs canada.json: 934 µs jeopardy.json: 34,514 µs">
|
||||
<rect class="nj-heat-0" x="225" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · sum 1.08× the time of the fastest library (fully validating) way: parse twitter.json: 398 µs citm_catalog.json: 972 µs canada.json: 3,501 µs jeopardy.json: 89,756 µs">
|
||||
<rect class="nj-heat-0" x="317" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="66" text-anchor="middle">1.08</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · select 1.00× the time of the fastest library (fully validating) twitter.json: 333 µs · structs (from_json) citm_catalog.json: 828 µs · parse canada.json: 1,368 µs · parse jeopardy.json: 89,876 µs · parse">
|
||||
<rect class="nj-heat-0" x="409" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit 1.00× the time of the fastest library (fully validating) way: editable twitter.json: 536 µs citm_catalog.json: 1,162 µs canada.json: 5,567 µs jeopardy.json: 192,323 µs">
|
||||
<rect class="nj-heat-0" x="501" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit, checking less 0.79× the time of the fastest fully validating library twitter.json: 530 µs · editable (source numbers) (validates fully) citm_catalog.json: 1,149 µs · editable (source numbers) (validates fully) canada.json: 2,188 µs · editable (source numbers) (validates fully) jeopardy.json: 192,323 µs · editable (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="547" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="60" text-anchor="middle">0.79</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify 1.00× the time of the fastest library (fully validating) way: parse + dump twitter.json: 518 µs citm_catalog.json: 1,045 µs canada.json: 5,240 µs jeopardy.json: 143,737 µs">
|
||||
<rect class="nj-heat-0" x="593" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify, checking less 0.80× the time of the fastest fully validating library twitter.json: 496 µs · parse + dump (source numbers) (validates fully) citm_catalog.json: 1,045 µs · parse + dump (validates fully) canada.json: 2,196 µs · parse + dump (source numbers) (validates fully) jeopardy.json: 143,206 µs · parse + dump (source numbers) (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="639" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="60" text-anchor="middle">0.80</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write 1.00× the time of the fastest library (fully validating) way: dump twitter.json: 156 µs citm_catalog.json: 251 µs canada.json: 3,842 µs jeopardy.json: 67,769 µs">
|
||||
<rect class="nj-heat-0" x="685" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="707.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write, checking less 0.64× the time of the fastest fully validating library way: dump (source numbers) twitter.json: 140 µs (validates fully) citm_catalog.json: 230 µs (validates fully) canada.json: 823 µs (validates fully) jeopardy.json: 65,376 µs (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="731" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="752.5" y="60" text-anchor="middle">0.64</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="752.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="102" text-anchor="end">yyjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · validate 1.94× the time of the fastest library (fully validating) twitter.json: 352 µs · insitu (copy untimed) citm_catalog.json: 837 µs · insitu (copy untimed) canada.json: 2,199 µs · read (raw numbers) jeopardy.json: 93,043 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-2" x="225" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="102" text-anchor="middle">1.94</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · sum 1.14× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 415 µs citm_catalog.json: 986 µs canada.json: 3,818 µs jeopardy.json: 97,586 µs">
|
||||
<rect class="nj-heat-0" x="317" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="102" text-anchor="middle">1.14</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · select 1.18× the time of the fastest library (fully validating) twitter.json: 366 µs · insitu (copy untimed) citm_catalog.json: 840 µs · insitu (copy untimed) canada.json: 2,204 µs · read (raw numbers) jeopardy.json: 96,172 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-1" x="409" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="102" text-anchor="middle">1.18</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · edit 1.37× the time of the fastest library (fully validating) way: insitu (copy untimed) + mut copy twitter.json: 746 µs citm_catalog.json: 1,526 µs canada.json: 7,479 µs jeopardy.json: 275,025 µs">
|
||||
<rect class="nj-heat-1" x="501" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="102" text-anchor="middle">1.37</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify 1.17× the time of the fastest library (fully validating) twitter.json: 626 µs · insitu (copy) + write citm_catalog.json: 1,160 µs · insitu (copy untimed) + write canada.json: 6,701 µs · insitu (copy untimed) + write jeopardy.json: 156,605 µs · insitu (copy untimed) + write (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-1" x="593" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="102" text-anchor="middle">1.17</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify, checking less 0.95× the time of the fastest fully validating library twitter.json: 626 µs · insitu (copy) + write (validates fully) citm_catalog.json: 1,160 µs · insitu (copy untimed) + write (validates fully) canada.json: 2,901 µs · read (raw numbers) + write (validates fully) jeopardy.json: 156,605 µs · insitu (copy untimed) + write (validates fully) copies each number's text instead of formatting it (YYJSON_READ_NUMBER_AS_RAW) (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-0" x="639" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="96" text-anchor="middle">0.95</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="109" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · write 1.11× the time of the fastest library (fully validating) way: write twitter.json: 215 µs citm_catalog.json: 319 µs canada.json: 3,360 µs jeopardy.json: 66,669 µs">
|
||||
<rect class="nj-heat-0" x="685" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="102" text-anchor="middle">1.11</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="138" text-anchor="end">sonic-cpp</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · validate, checking less 2.32× the time of the fastest fully validating library way: Document twitter.json: 403 µs citm_catalog.json: 932 µs canada.json: 3,349 µs jeopardy.json: 98,511 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="225" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="132" text-anchor="middle">2.32</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="270" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · sum, checking less 1.24× the time of the fastest fully validating library way: Document twitter.json: 456 µs citm_catalog.json: 1,115 µs canada.json: 3,980 µs jeopardy.json: 105,081 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="317" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="132" text-anchor="middle">1.24</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="362" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · select, checking less 1.45× the time of the fastest fully validating library way: Document twitter.json: 407 µs citm_catalog.json: 948 µs canada.json: 3,464 µs jeopardy.json: 110,885 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="409" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="132" text-anchor="middle">1.45</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="454" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · edit, checking less 1.21× the time of the fastest fully validating library way: Document twitter.json: 620 µs citm_catalog.json: 1,438 µs canada.json: 8,495 µs jeopardy.json: 186,078 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="501" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="132" text-anchor="middle">1.21</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="546" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · minify, checking less 1.36× the time of the fastest fully validating library way: Document + Serialize twitter.json: 675 µs citm_catalog.json: 1,417 µs canada.json: 8,958 µs jeopardy.json: 164,630 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="593" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="132" text-anchor="middle">1.36</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="638" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · write 1.45× the time of the fastest library (fully validating) way: Serialize twitter.json: 249 µs citm_catalog.json: 509 µs canada.json: 5,074 µs jeopardy.json: 69,916 µs">
|
||||
<rect class="nj-heat-1" x="685" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="138" text-anchor="middle">1.45</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="174" text-anchor="end">simdjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · validate 2.11× the time of the fastest library (fully validating) way: D​OM twitter.json: 301 µs citm_catalog.json: 695 µs canada.json: 3,337 µs jeopardy.json: 120,982 µs">
|
||||
<rect class="nj-heat-2" x="225" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="174" text-anchor="middle">2.11</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · sum 1.00× the time of the fastest library (fully validating) way: On-Demand twitter.json: 348 µs citm_catalog.json: 805 µs canada.json: 3,452 µs jeopardy.json: 92,769 µs">
|
||||
<rect class="nj-heat-0" x="317" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="174" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select 1.27× the time of the fastest library (fully validating) way: D​OM twitter.json: 313 µs citm_catalog.json: 699 µs canada.json: 3,325 µs jeopardy.json: 122,556 µs">
|
||||
<rect class="nj-heat-1" x="409" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="174" text-anchor="middle">1.27</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select, checking less 0.54× the time of the fastest fully validating library twitter.json: 180 µs · On-Demand citm_catalog.json: 496 µs · On-Demand (key selectors) canada.json: 690 µs · On-Demand (key selectors) jeopardy.json: 48,272 µs · On-Demand (key selectors) reads lazily: On-Demand reads only what you ask for and steps over the rest by matching brackets">
|
||||
<rect class="nj-heat-0" x="455" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="168" text-anchor="middle">0.54</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="181" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · edit simdjson's documents are read-only: it has no A​PI to change a value and write the result">
|
||||
<rect class="nj-heat-na" x="501" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-tick" x="546" y="174">n/a</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify 1.54× the time of the fastest library (fully validating) way: D​OM + to_string twitter.json: 714 µs citm_catalog.json: 1,318 µs canada.json: 9,135 µs jeopardy.json: 269,597 µs">
|
||||
<rect class="nj-heat-2" x="593" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="174" text-anchor="middle">1.54</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify, checking less 0.17× the time of the fastest fully validating library way: minify twitter.json: 99.9 µs citm_catalog.json: 278 µs canada.json: 312 µs jeopardy.json: 42,644 µs simdjson::minify() only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="168" text-anchor="middle">0.17</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="181" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · write 2.10× the time of the fastest library (fully validating) way: to_string twitter.json: 361 µs citm_catalog.json: 614 µs canada.json: 5,609 µs jeopardy.json: 158,492 µs">
|
||||
<rect class="nj-heat-2" x="685" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="174" text-anchor="middle">2.10</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="210" text-anchor="end">sonic-rs (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · validate 1.93× the time of the fastest library (fully validating) way: IgnoredAny twitter.json: 501 µs citm_catalog.json: 970 µs canada.json: 2,249 µs jeopardy.json: 54,369 µs">
|
||||
<rect class="nj-heat-2" x="225" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="210" text-anchor="middle">1.93</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · sum 1.13× the time of the fastest library (fully validating) way: visitor twitter.json: 501 µs citm_catalog.json: 1,123 µs canada.json: 4,397 µs jeopardy.json: 59,583 µs">
|
||||
<rect class="nj-heat-0" x="317" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="210" text-anchor="middle">1.13</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · select 1.34× the time of the fastest library (fully validating) way: structs twitter.json: 504 µs citm_catalog.json: 1,033 µs canada.json: 2,328 µs jeopardy.json: 90,486 µs">
|
||||
<rect class="nj-heat-1" x="409" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="210" text-anchor="middle">1.34</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · edit 1.90× the time of the fastest library (fully validating) way: Value twitter.json: 1,197 µs citm_catalog.json: 2,389 µs canada.json: 7,744 µs jeopardy.json: 390,952 µs">
|
||||
<rect class="nj-heat-2" x="501" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="210" text-anchor="middle">1.90</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · minify 1.71× the time of the fastest library (fully validating) way: Value twitter.json: 1,000 µs citm_catalog.json: 2,097 µs canada.json: 7,795 µs jeopardy.json: 215,280 µs">
|
||||
<rect class="nj-heat-2" x="593" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="210" text-anchor="middle">1.71</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · write 2.04× the time of the fastest library (fully validating) way: Value twitter.json: 434 µs citm_catalog.json: 927 µs canada.json: 3,987 µs jeopardy.json: 109,176 µs">
|
||||
<rect class="nj-heat-2" x="685" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="210" text-anchor="middle">2.04</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="246" text-anchor="end">Boost.J​SON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · validate 1.99× the time of the fastest library (fully validating) way: S​AX (numbers: none) twitter.json: 690 µs citm_catalog.json: 917 µs canada.json: 1,676 µs jeopardy.json: 62,781 µs">
|
||||
<rect class="nj-heat-2" x="225" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="246" text-anchor="middle">1.99</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · sum 1.27× the time of the fastest library (fully validating) way: S​AX twitter.json: 699 µs citm_catalog.json: 957 µs canada.json: 5,835 µs jeopardy.json: 59,656 µs">
|
||||
<rect class="nj-heat-1" x="317" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="246" text-anchor="middle">1.27</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · select 2.20× the time of the fastest library (fully validating) twitter.json: 887 µs · parse_into structs citm_catalog.json: 1,270 µs · parse_into structs canada.json: 7,292 µs · parse jeopardy.json: 95,866 µs · parse_into structs">
|
||||
<rect class="nj-heat-2" x="409" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="246" text-anchor="middle">2.20</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · edit 2.30× the time of the fastest library (fully validating) way: parse twitter.json: 1,767 µs citm_catalog.json: 2,493 µs canada.json: 12,767 µs jeopardy.json: 331,310 µs">
|
||||
<rect class="nj-heat-2" x="501" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="246" text-anchor="middle">2.30</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · minify 2.65× the time of the fastest library (fully validating) way: parse + serialize twitter.json: 1,974 µs citm_catalog.json: 2,525 µs canada.json: 12,748 µs jeopardy.json: 314,299 µs">
|
||||
<rect class="nj-heat-3" x="593" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="246" text-anchor="middle">2.65</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · write 2.36× the time of the fastest library (fully validating) way: serialize twitter.json: 469 µs citm_catalog.json: 830 µs canada.json: 5,659 µs jeopardy.json: 144,174 µs">
|
||||
<rect class="nj-heat-2" x="685" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="246" text-anchor="middle">2.36</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="282" text-anchor="end">simd-json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · validate 3.62× the time of the fastest library (fully validating) way: tape (copy) twitter.json: 567 µs citm_catalog.json: 1,430 µs canada.json: 4,359 µs jeopardy.json: 207,551 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="225" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="282" text-anchor="middle">3.62</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · sum 1.91× the time of the fastest library (fully validating) way: visitor (copy) twitter.json: 681 µs citm_catalog.json: 1,650 µs canada.json: 5,083 µs jeopardy.json: 210,185 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-2" x="317" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="282" text-anchor="middle">1.91</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · select 2.56× the time of the fastest library (fully validating) way: structs (copy) twitter.json: 679 µs citm_catalog.json: 1,731 µs canada.json: 5,144 µs jeopardy.json: 239,164 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="409" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="282" text-anchor="middle">2.56</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · edit 2.87× the time of the fastest library (fully validating) twitter.json: 1,862 µs · borrowed (copy) citm_catalog.json: 4,194 µs · borrowed (copy) canada.json: 14,896 µs · owned (copy) jeopardy.json: 391,369 µs · borrowed (copy) (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="501" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="282" text-anchor="middle">2.87</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · minify 3.35× the time of the fastest library (fully validating) way: borrowed (copy) twitter.json: 1,889 µs citm_catalog.json: 4,196 µs canada.json: 15,716 µs jeopardy.json: 414,377 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="593" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="282" text-anchor="middle">3.35</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · write 2.32× the time of the fastest library (fully validating) way: borrowed twitter.json: 582 µs citm_catalog.json: 800 µs canada.json: 5,147 µs jeopardy.json: 122,623 µs">
|
||||
<rect class="nj-heat-2" x="685" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="282" text-anchor="middle">2.32</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="318" text-anchor="end">RapidJSON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate 3.71× the time of the fastest library (fully validating) twitter.json: 1,166 µs · insitu (copy untimed) citm_catalog.json: 1,553 µs · S​AX (string stream, default precision) canada.json: 3,875 µs · S​AX (string stream, default precision) jeopardy.json: 114,704 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="225" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="318" text-anchor="middle">3.71</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate, checking less 3.41× the time of the fastest fully validating library twitter.json: 1,012 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,434 µs · S​AX (default precision) (no encoding check) canada.json: 3,875 µs · S​AX (string stream, default precision) (validates fully) jeopardy.json: 102,635 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="271" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="312" text-anchor="middle">3.41</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="325" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum 2.23× the time of the fastest library (fully validating) twitter.json: 1,221 µs · insitu (copy untimed) citm_catalog.json: 1,717 µs · S​AX (string stream) canada.json: 9,435 µs · S​AX (string stream) jeopardy.json: 112,158 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-2" x="317" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="339.5" y="318" text-anchor="middle">2.23</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum, checking less 2.09× the time of the fastest fully validating library twitter.json: 1,063 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,635 µs · S​AX (string stream) (no encoding check) canada.json: 9,368 µs · S​AX (string stream) (no encoding check) jeopardy.json: 105,845 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-2" x="363" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="384.5" y="312" text-anchor="middle">2.09</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="384.5" y="325" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select 2.91× the time of the fastest library (fully validating) twitter.json: 1,180 µs · insitu (copy untimed) citm_catalog.json: 1,693 µs · insitu (copy untimed) canada.json: 10,390 µs · Document (string stream) jeopardy.json: 116,394 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="409" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="318" text-anchor="middle">2.91</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select, checking less 2.73× the time of the fastest fully validating library twitter.json: 1,022 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,648 µs · insitu (copy untimed) (no encoding check) canada.json: 10,390 µs · Document (string stream) (validates fully) jeopardy.json: 108,290 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="455" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="312" text-anchor="middle">2.73</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="325" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit 2.41× the time of the fastest library (fully validating) twitter.json: 1,865 µs · insitu (copy untimed) citm_catalog.json: 2,616 µs · insitu (copy untimed) canada.json: 18,812 µs · Document (string stream) jeopardy.json: 245,724 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-2" x="501" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="318" text-anchor="middle">2.41</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit, checking less 2.34× the time of the fastest fully validating library twitter.json: 1,737 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 2,595 µs · insitu (copy untimed) (no encoding check) canada.json: 18,812 µs · Document (string stream) (validates fully) jeopardy.json: 234,669 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-2" x="547" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="312" text-anchor="middle">2.34</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="325" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify 2.68× the time of the fastest library (fully validating) way: S​AX to Writer (string stream) twitter.json: 1,949 µs citm_catalog.json: 2,382 µs canada.json: 19,548 µs jeopardy.json: 231,979 µs">
|
||||
<rect class="nj-heat-3" x="593" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="318" text-anchor="middle">2.68</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify, checking less 2.42× the time of the fastest fully validating library twitter.json: 1,880 µs · S​AX to Writer (string stream) (no encoding check) citm_catalog.json: 2,314 µs · S​AX to Writer (string stream) (no encoding check) canada.json: 14,400 µs · S​AX to Writer (raw numbers) (validates fully) jeopardy.json: 224,249 µs · S​AX to Writer (string stream) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it) copies each number's text instead of formatting it (kParseNumbersAsStringsFlag)">
|
||||
<rect class="nj-heat-2" x="639" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="312" text-anchor="middle">2.42</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="325" text-anchor="middle">U N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · write 2.97× the time of the fastest library (fully validating) way: Writer twitter.json: 678 µs citm_catalog.json: 979 µs canada.json: 9,095 µs jeopardy.json: 131,408 µs">
|
||||
<rect class="nj-heat-3" x="685" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="318" text-anchor="middle">2.97</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="354" text-anchor="end">serde_json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate 2.39× the time of the fastest library (fully validating) way: from_utf8 + IgnoredAny twitter.json: 624 µs citm_catalog.json: 1,440 µs canada.json: 2,406 µs jeopardy.json: 64,720 µs">
|
||||
<rect class="nj-heat-2" x="225" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="354" text-anchor="middle">2.39</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate, checking less 2.14× the time of the fastest fully validating library way: IgnoredAny twitter.json: 484 µs citm_catalog.json: 1,370 µs canada.json: 2,314 µs jeopardy.json: 58,247 µs trusts U​TF-8 in the strings it skips (from_slice); strings it reads are checked">
|
||||
<rect class="nj-heat-2" x="271" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="348" text-anchor="middle">2.14</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="361" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · sum 2.36× the time of the fastest library (fully validating) way: visitor twitter.json: 1,311 µs citm_catalog.json: 2,288 µs canada.json: 7,127 µs jeopardy.json: 129,497 µs">
|
||||
<rect class="nj-heat-2" x="317" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="354" text-anchor="middle">2.36</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · select 1.71× the time of the fastest library (fully validating) way: from_utf8 + structs twitter.json: 701 µs citm_catalog.json: 1,532 µs canada.json: 2,529 µs jeopardy.json: 107,316 µs">
|
||||
<rect class="nj-heat-2" x="409" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="354" text-anchor="middle">1.71</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · edit 4.53× the time of the fastest library (fully validating) way: Value twitter.json: 4,042 µs citm_catalog.json: 6,586 µs canada.json: 16,631 µs jeopardy.json: 632,766 µs">
|
||||
<rect class="nj-heat-3" x="501" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="354" text-anchor="middle">4.53</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · minify 4.89× the time of the fastest library (fully validating) way: Value twitter.json: 4,012 µs citm_catalog.json: 6,583 µs canada.json: 17,306 µs jeopardy.json: 509,702 µs">
|
||||
<rect class="nj-heat-3" x="593" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="354" text-anchor="middle">4.89</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · write 2.25× the time of the fastest library (fully validating) way: Value twitter.json: 550 µs citm_catalog.json: 887 µs canada.json: 4,005 µs jeopardy.json: 134,163 µs">
|
||||
<rect class="nj-heat-2" x="685" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="354" text-anchor="middle">2.25</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="390" text-anchor="end">Glaze</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · validate 2.86× the time of the fastest library (fully validating) way: validate_json twitter.json: 712 µs citm_catalog.json: 1,983 µs canada.json: 2,625 µs jeopardy.json: 76,759 µs">
|
||||
<rect class="nj-heat-3" x="225" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="390" text-anchor="middle">2.86</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · sum 4.16× the time of the fastest library (fully validating) way: generic (double, strict) twitter.json: 2,483 µs citm_catalog.json: 4,413 µs canada.json: 10,532 µs jeopardy.json: 231,505 µs">
|
||||
<rect class="nj-heat-3" x="317" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="390" text-anchor="middle">4.16</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select 1.79× the time of the fastest library (fully validating) way: structs (validate_skipped) twitter.json: 606 µs citm_catalog.json: 2,476 µs canada.json: 2,557 µs jeopardy.json: 89,957 µs">
|
||||
<rect class="nj-heat-2" x="409" y="369" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="390" text-anchor="middle">1.79</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select, checking less 0.58× the time of the fastest fully validating library way: structs twitter.json: 344 µs citm_catalog.json: 402 µs canada.json: 417 µs jeopardy.json: 67,467 µs reads into structs and steps over fields it doesn't know without checking them (validate_skipped checks them too)">
|
||||
<rect class="nj-heat-0" x="455" y="369" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="384" text-anchor="middle">0.58</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="397" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · edit 4.47× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 3,389 µs citm_catalog.json: 6,002 µs canada.json: 21,598 µs jeopardy.json: 607,767 µs">
|
||||
<rect class="nj-heat-3" x="501" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="390" text-anchor="middle">4.47</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify 4.81× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 3,685 µs citm_catalog.json: 5,942 µs canada.json: 22,138 µs jeopardy.json: 450,322 µs">
|
||||
<rect class="nj-heat-3" x="593" y="369" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="390" text-anchor="middle">4.81</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify, checking less 0.78× the time of the fastest fully validating library way: minify_json twitter.json: 442 µs citm_catalog.json: 1,292 µs canada.json: 2,726 µs jeopardy.json: 97,377 µs minify_json only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="369" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="384" text-anchor="middle">0.78</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="397" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · write 1.96× the time of the fastest library (fully validating) way: generic twitter.json: 381 µs citm_catalog.json: 730 µs canada.json: 4,071 µs jeopardy.json: 131,946 µs">
|
||||
<rect class="nj-heat-2" x="685" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="390" text-anchor="middle">1.96</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="426" text-anchor="end">nlohmann/json json</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · validate 2.96× the time of the fastest library (fully validating) way: accept twitter.json: 683 µs citm_catalog.json: 1,419 µs canada.json: 4,559 µs jeopardy.json: 74,331 µs">
|
||||
<rect class="nj-heat-3" x="225" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="426" text-anchor="middle">2.96</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · sum 1.70× the time of the fastest library (fully validating) way: sax twitter.json: 814 µs citm_catalog.json: 1,666 µs canada.json: 5,690 µs jeopardy.json: 97,414 µs">
|
||||
<rect class="nj-heat-2" x="317" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="426" text-anchor="middle">1.70</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · select 7.12× the time of the fastest library (fully validating) twitter.json: 3,360 µs · structs (from_json) citm_catalog.json: 5,268 µs · structs (from_json) canada.json: 12,006 µs · structs (from_json) jeopardy.json: 410,221 µs · parse">
|
||||
<rect class="nj-heat-4" x="409" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="426" text-anchor="middle">7.12</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · edit 3.83× the time of the fastest library (fully validating) way: ordered_json twitter.json: 2,832 µs citm_catalog.json: 4,970 µs canada.json: 15,806 µs jeopardy.json: 647,704 µs">
|
||||
<rect class="nj-heat-3" x="501" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="426" text-anchor="middle">3.83</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · minify 4.79× the time of the fastest library (fully validating) way: parse + dump twitter.json: 4,196 µs citm_catalog.json: 5,806 µs canada.json: 16,626 µs jeopardy.json: 529,560 µs">
|
||||
<rect class="nj-heat-3" x="593" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="426" text-anchor="middle">4.79</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · write 1.91× the time of the fastest library (fully validating) way: dump twitter.json: 444 µs citm_catalog.json: 640 µs canada.json: 4,089 µs jeopardy.json: 117,316 µs">
|
||||
<rect class="nj-heat-2" x="685" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="426" text-anchor="middle">1.91</text>
|
||||
</g>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="472">time relative to the fastest fully validating library, less is better</text>
|
||||
<g><rect class="nj-heat-0" x="8" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="46" y="496" text-anchor="middle">below 1.15</text></g>
|
||||
<g><rect class="nj-heat-1" x="88" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="126" y="496" text-anchor="middle">1.15 to 1.5</text></g>
|
||||
<g><rect class="nj-heat-2" x="168" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="206" y="496" text-anchor="middle">1.5 to 2.5</text></g>
|
||||
<g><rect class="nj-heat-3" x="248" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="286" y="496" text-anchor="middle">2.5 to 5</text></g>
|
||||
<g><rect class="nj-heat-4" x="328" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="366" y="496" text-anchor="middle">5 and more</text></g>
|
||||
<rect class="nj-heat-na" x="420" y="482" width="40" height="20" rx="3"/>
|
||||
<text class="nj-charts-tick" x="440" y="496">n/a</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="468" y="496">no A​PI for it</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 45 KiB |
@@ -1,374 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--blog nj-charts--heat" viewBox="0 0 784 510" role="img" aria-labelledby="nj-blog-uc-x86-gcc13 nj-blog-uc-x86-gcc13-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-blog-uc-x86-gcc13">Use cases: time of each library relative to the fastest, x86-64 with G​CC 13</title>
|
||||
<desc id="nj-blog-uc-x86-gcc13-d">Table of relative times, libraries by use case. nlohmann/json json_document validate: 1.00; nlohmann/json json_document sum: 1.08; nlohmann/json json_document select: 1.00; nlohmann/json json_document edit: 1.00 (0.83 doing less, N); nlohmann/json json_document minify: 1.00 (0.83 doing less, N); nlohmann/json json_document write: 1.00 (0.71 doing less, N); yyjson validate: 1.81; yyjson sum: 1.28; yyjson select: 1.22; yyjson edit: 1.49; yyjson minify: 1.27 (0.97 doing less, N); yyjson write: 1.14; sonic-cpp validate: no fully validating way (2.24 doing less, U); sonic-cpp sum: no fully validating way (1.28 doing less, U); sonic-cpp select: no fully validating way (1.53 doing less, U); sonic-cpp edit: no fully validating way (1.26 doing less, U); sonic-cpp minify: no fully validating way (1.42 doing less, U); sonic-cpp write: 1.50; simdjson validate: 2.01; simdjson sum: 1.00; simdjson select: 1.35 (0.57 doing less, P); simdjson edit: n/a; simdjson minify: 1.58 (0.22 doing less, P); simdjson write: 2.07; sonic-rs (Rust) validate: 1.79; sonic-rs (Rust) sum: 1.11; sonic-rs (Rust) select: 1.37; sonic-rs (Rust) edit: 1.91; sonic-rs (Rust) minify: 1.73; sonic-rs (Rust) write: 2.07; Boost.J​SON validate: 1.88; Boost.J​SON sum: 1.33; Boost.J​SON select: 2.30; Boost.J​SON edit: 2.55; Boost.J​SON minify: 2.92; Boost.J​SON write: 2.56; simd-json (Rust) validate: 3.35; simd-json (Rust) sum: 1.88; simd-json (Rust) select: 2.61; simd-json (Rust) edit: 2.89; simd-json (Rust) minify: 3.39; simd-json (Rust) write: 2.35; serde_json (Rust) validate: 2.22 (1.98 doing less, U); serde_json (Rust) sum: 2.32; serde_json (Rust) select: 1.75; serde_json (Rust) edit: 4.55; serde_json (Rust) minify: 4.94; serde_json (Rust) write: 2.28; Glaze validate: 2.21; Glaze sum: 4.04; Glaze select: 1.44 (0.60 doing less, P); Glaze edit: 4.85; Glaze minify: 5.10 (0.73 doing less, P); Glaze write: 1.84; nlohmann/json json validate: 2.74; nlohmann/json json sum: 1.67; nlohmann/json json select: 7.24; nlohmann/json json edit: 3.81; nlohmann/json json minify: 4.79; nlohmann/json json write: 1.99; RapidJSON validate: 4.50 (3.40 doing less, U); RapidJSON sum: 2.98 (2.29 doing less, U); RapidJSON select: 3.84 (3.06 doing less, U); RapidJSON edit: 2.92 (2.58 doing less, U); RapidJSON minify: 3.64 (2.64 doing less, U N); RapidJSON write: 3.11.</desc>
|
||||
<text class="nj-charts-tick" x="270" y="34">validate</text>
|
||||
<text class="nj-charts-tick" x="362" y="34">sum</text>
|
||||
<text class="nj-charts-tick" x="454" y="34">select</text>
|
||||
<text class="nj-charts-tick" x="546" y="34">edit</text>
|
||||
<text class="nj-charts-tick" x="638" y="34">minify</text>
|
||||
<text class="nj-charts-tick" x="730" y="34">write</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="66" text-anchor="end">nlohmann/json json_document</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · validate 1.00× the time of the fastest library (fully validating) way: accept twitter.json: 271 µs citm_catalog.json: 609 µs canada.json: 1,011 µs jeopardy.json: 34,722 µs">
|
||||
<rect class="nj-heat-0" x="225" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · sum 1.08× the time of the fastest library (fully validating) way: parse twitter.json: 392 µs citm_catalog.json: 946 µs canada.json: 3,888 µs jeopardy.json: 89,044 µs">
|
||||
<rect class="nj-heat-0" x="317" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="66" text-anchor="middle">1.08</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · select 1.00× the time of the fastest library (fully validating) way: parse twitter.json: 332 µs citm_catalog.json: 765 µs canada.json: 1,390 µs jeopardy.json: 88,202 µs">
|
||||
<rect class="nj-heat-0" x="409" y="45" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit 1.00× the time of the fastest library (fully validating) way: editable twitter.json: 532 µs citm_catalog.json: 1,116 µs canada.json: 5,714 µs jeopardy.json: 192,363 µs">
|
||||
<rect class="nj-heat-0" x="501" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · edit, checking less 0.83× the time of the fastest fully validating library twitter.json: 532 µs · editable (validates fully) citm_catalog.json: 1,116 µs · editable (validates fully) canada.json: 2,702 µs · editable (source numbers) (validates fully) jeopardy.json: 192,363 µs · editable (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="547" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="60" text-anchor="middle">0.83</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify 1.00× the time of the fastest library (fully validating) twitter.json: 483 µs · parse + dump citm_catalog.json: 1,014 µs · parse + dump canada.json: 5,459 µs · parse_copy + dump jeopardy.json: 146,320 µs · parse + dump">
|
||||
<rect class="nj-heat-0" x="593" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · minify, checking less 0.83× the time of the fastest fully validating library twitter.json: 483 µs · parse + dump (validates fully) citm_catalog.json: 1,014 µs · parse + dump (validates fully) canada.json: 2,620 µs · parse + dump (source numbers) (validates fully) jeopardy.json: 146,320 µs · parse + dump (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="639" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="60" text-anchor="middle">0.83</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write 1.00× the time of the fastest library (fully validating) way: dump twitter.json: 150 µs citm_catalog.json: 260 µs canada.json: 3,861 µs jeopardy.json: 63,958 µs">
|
||||
<rect class="nj-heat-0" x="685" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="707.5" y="66" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json_document · write, checking less 0.71× the time of the fastest fully validating library twitter.json: 148 µs · dump (source numbers) (validates fully) citm_catalog.json: 260 µs · dump (validates fully) canada.json: 998 µs · dump (source numbers) (validates fully) jeopardy.json: 63,958 µs · dump (validates fully) copies each number's text instead of formatting it (number_format::source)">
|
||||
<rect class="nj-heat-0" x="731" y="45" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="752.5" y="60" text-anchor="middle">0.71</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="752.5" y="73" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="102" text-anchor="end">yyjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · validate 1.81× the time of the fastest library (fully validating) twitter.json: 348 µs · insitu (copy untimed) citm_catalog.json: 878 µs · insitu (copy untimed) canada.json: 2,256 µs · read (raw numbers) jeopardy.json: 90,959 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-2" x="225" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="102" text-anchor="middle">1.81</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · sum 1.28× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 407 µs citm_catalog.json: 1,045 µs canada.json: 6,021 µs jeopardy.json: 99,764 µs">
|
||||
<rect class="nj-heat-1" x="317" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="102" text-anchor="middle">1.28</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · select 1.22× the time of the fastest library (fully validating) twitter.json: 361 µs · insitu (copy untimed) citm_catalog.json: 880 µs · insitu (copy untimed) canada.json: 2,236 µs · read (raw numbers) jeopardy.json: 98,637 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-1" x="409" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="102" text-anchor="middle">1.22</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · edit 1.49× the time of the fastest library (fully validating) way: insitu (copy untimed) + mut copy twitter.json: 761 µs citm_catalog.json: 1,590 µs canada.json: 9,860 µs jeopardy.json: 271,227 µs">
|
||||
<rect class="nj-heat-1" x="501" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="102" text-anchor="middle">1.49</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify 1.27× the time of the fastest library (fully validating) twitter.json: 592 µs · insitu (copy untimed) + write citm_catalog.json: 1,205 µs · insitu (copy untimed) + write canada.json: 9,008 µs · read + write jeopardy.json: 158,577 µs · insitu (copy untimed) + write">
|
||||
<rect class="nj-heat-1" x="593" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="102" text-anchor="middle">1.27</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · minify, checking less 0.97× the time of the fastest fully validating library twitter.json: 592 µs · insitu (copy untimed) + write (validates fully) citm_catalog.json: 1,205 µs · insitu (copy untimed) + write (validates fully) canada.json: 3,106 µs · read (raw numbers) + write (validates fully) jeopardy.json: 158,577 µs · insitu (copy untimed) + write (validates fully) copies each number's text instead of formatting it (YYJSON_READ_NUMBER_AS_RAW)">
|
||||
<rect class="nj-heat-0" x="639" y="81" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="96" text-anchor="middle">0.97</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="109" text-anchor="middle">N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="yyjson · write 1.14× the time of the fastest library (fully validating) way: write twitter.json: 204 µs citm_catalog.json: 327 µs canada.json: 3,748 µs jeopardy.json: 65,989 µs">
|
||||
<rect class="nj-heat-0" x="685" y="81" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="102" text-anchor="middle">1.14</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="138" text-anchor="end">sonic-cpp</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · validate, checking less 2.24× the time of the fastest fully validating library way: Document twitter.json: 408 µs citm_catalog.json: 1,028 µs canada.json: 3,622 µs jeopardy.json: 96,080 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="225" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="132" text-anchor="middle">2.24</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="270" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · sum, checking less 1.28× the time of the fastest fully validating library way: Document twitter.json: 460 µs citm_catalog.json: 1,210 µs canada.json: 4,295 µs jeopardy.json: 107,092 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="317" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="132" text-anchor="middle">1.28</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="362" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · select, checking less 1.53× the time of the fastest fully validating library way: Document twitter.json: 413 µs citm_catalog.json: 1,043 µs canada.json: 3,695 µs jeopardy.json: 108,297 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-2" x="409" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="132" text-anchor="middle">1.53</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="454" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · edit, checking less 1.26× the time of the fastest fully validating library way: Document twitter.json: 637 µs citm_catalog.json: 1,559 µs canada.json: 8,936 µs jeopardy.json: 186,232 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="501" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="132" text-anchor="middle">1.26</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="546" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · minify, checking less 1.42× the time of the fastest fully validating library way: Document + Serialize twitter.json: 695 µs citm_catalog.json: 1,541 µs canada.json: 8,838 µs jeopardy.json: 168,901 µs trusts U​TF-8: sonic-cpp 1.0.2 doesn't check it">
|
||||
<rect class="nj-heat-1" x="593" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="132" text-anchor="middle">1.42</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="638" y="145" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-cpp · write 1.50× the time of the fastest library (fully validating) way: Serialize twitter.json: 256 µs citm_catalog.json: 541 µs canada.json: 5,120 µs jeopardy.json: 69,546 µs">
|
||||
<rect class="nj-heat-2" x="685" y="117" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="138" text-anchor="middle">1.50</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="174" text-anchor="end">simdjson</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · validate 2.01× the time of the fastest library (fully validating) way: D​OM twitter.json: 311 µs citm_catalog.json: 780 µs canada.json: 3,351 µs jeopardy.json: 116,704 µs">
|
||||
<rect class="nj-heat-2" x="225" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="174" text-anchor="middle">2.01</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · sum 1.00× the time of the fastest library (fully validating) way: On-Demand twitter.json: 356 µs citm_catalog.json: 812 µs canada.json: 3,435 µs jeopardy.json: 96,250 µs">
|
||||
<rect class="nj-heat-0" x="317" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="174" text-anchor="middle">1.00</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select 1.35× the time of the fastest library (fully validating) way: D​OM twitter.json: 324 µs citm_catalog.json: 756 µs canada.json: 3,409 µs jeopardy.json: 123,214 µs">
|
||||
<rect class="nj-heat-1" x="409" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="174" text-anchor="middle">1.35</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · select, checking less 0.57× the time of the fastest fully validating library twitter.json: 184 µs · On-Demand (key selectors) citm_catalog.json: 509 µs · On-Demand canada.json: 700 µs · On-Demand jeopardy.json: 48,614 µs · On-Demand reads lazily: On-Demand reads only what you ask for and steps over the rest by matching brackets">
|
||||
<rect class="nj-heat-0" x="455" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="168" text-anchor="middle">0.57</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="181" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · edit simdjson's documents are read-only: it has no A​PI to change a value and write the result">
|
||||
<rect class="nj-heat-na" x="501" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-tick" x="546" y="174">n/a</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify 1.58× the time of the fastest library (fully validating) way: D​OM + to_string twitter.json: 742 µs citm_catalog.json: 1,393 µs canada.json: 8,808 µs jeopardy.json: 266,718 µs">
|
||||
<rect class="nj-heat-2" x="593" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="174" text-anchor="middle">1.58</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · minify, checking less 0.22× the time of the fastest fully validating library way: minify twitter.json: 123 µs citm_catalog.json: 337 µs canada.json: 433 µs jeopardy.json: 47,040 µs simdjson::minify() only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="153" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="168" text-anchor="middle">0.22</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="181" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simdjson · write 2.07× the time of the fastest library (fully validating) way: to_string twitter.json: 359 µs citm_catalog.json: 637 µs canada.json: 4,999 µs jeopardy.json: 154,364 µs">
|
||||
<rect class="nj-heat-2" x="685" y="153" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="174" text-anchor="middle">2.07</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="210" text-anchor="end">sonic-rs (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · validate 1.79× the time of the fastest library (fully validating) way: IgnoredAny twitter.json: 501 µs citm_catalog.json: 970 µs canada.json: 2,249 µs jeopardy.json: 54,369 µs">
|
||||
<rect class="nj-heat-2" x="225" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="210" text-anchor="middle">1.79</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · sum 1.11× the time of the fastest library (fully validating) way: visitor twitter.json: 501 µs citm_catalog.json: 1,123 µs canada.json: 4,397 µs jeopardy.json: 59,583 µs">
|
||||
<rect class="nj-heat-0" x="317" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="210" text-anchor="middle">1.11</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · select 1.37× the time of the fastest library (fully validating) way: structs twitter.json: 504 µs citm_catalog.json: 1,033 µs canada.json: 2,328 µs jeopardy.json: 90,486 µs">
|
||||
<rect class="nj-heat-1" x="409" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="210" text-anchor="middle">1.37</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · edit 1.91× the time of the fastest library (fully validating) way: Value twitter.json: 1,197 µs citm_catalog.json: 2,389 µs canada.json: 7,744 µs jeopardy.json: 390,952 µs">
|
||||
<rect class="nj-heat-2" x="501" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="210" text-anchor="middle">1.91</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · minify 1.73× the time of the fastest library (fully validating) way: Value twitter.json: 1,000 µs citm_catalog.json: 2,097 µs canada.json: 7,795 µs jeopardy.json: 215,280 µs">
|
||||
<rect class="nj-heat-2" x="593" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="210" text-anchor="middle">1.73</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="sonic-rs (Rust) · write 2.07× the time of the fastest library (fully validating) way: Value twitter.json: 434 µs citm_catalog.json: 927 µs canada.json: 3,987 µs jeopardy.json: 109,176 µs">
|
||||
<rect class="nj-heat-2" x="685" y="189" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="210" text-anchor="middle">2.07</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="246" text-anchor="end">Boost.J​SON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · validate 1.88× the time of the fastest library (fully validating) way: S​AX (numbers: none) twitter.json: 710 µs citm_catalog.json: 969 µs canada.json: 1,718 µs jeopardy.json: 61,476 µs">
|
||||
<rect class="nj-heat-2" x="225" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="246" text-anchor="middle">1.88</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · sum 1.33× the time of the fastest library (fully validating) way: S​AX twitter.json: 734 µs citm_catalog.json: 1,030 µs canada.json: 6,103 µs jeopardy.json: 64,382 µs">
|
||||
<rect class="nj-heat-1" x="317" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="246" text-anchor="middle">1.33</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · select 2.30× the time of the fastest library (fully validating) twitter.json: 884 µs · parse_into structs citm_catalog.json: 1,380 µs · parse_into structs canada.json: 7,217 µs · parse jeopardy.json: 99,078 µs · parse_into structs">
|
||||
<rect class="nj-heat-2" x="409" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="246" text-anchor="middle">2.30</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · edit 2.55× the time of the fastest library (fully validating) way: parse twitter.json: 1,963 µs citm_catalog.json: 2,936 µs canada.json: 13,414 µs jeopardy.json: 356,244 µs">
|
||||
<rect class="nj-heat-3" x="501" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="246" text-anchor="middle">2.55</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · minify 2.92× the time of the fastest library (fully validating) way: parse + serialize twitter.json: 2,086 µs citm_catalog.json: 2,919 µs canada.json: 13,974 µs jeopardy.json: 334,468 µs">
|
||||
<rect class="nj-heat-3" x="593" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="246" text-anchor="middle">2.92</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Boost.J​SON · write 2.56× the time of the fastest library (fully validating) way: serialize twitter.json: 480 µs citm_catalog.json: 1,016 µs canada.json: 6,154 µs jeopardy.json: 139,022 µs">
|
||||
<rect class="nj-heat-3" x="685" y="225" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="246" text-anchor="middle">2.56</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="282" text-anchor="end">simd-json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · validate 3.35× the time of the fastest library (fully validating) way: tape (copy) twitter.json: 567 µs citm_catalog.json: 1,430 µs canada.json: 4,359 µs jeopardy.json: 207,551 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="225" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="282" text-anchor="middle">3.35</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · sum 1.88× the time of the fastest library (fully validating) way: visitor (copy) twitter.json: 681 µs citm_catalog.json: 1,650 µs canada.json: 5,083 µs jeopardy.json: 210,185 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-2" x="317" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="282" text-anchor="middle">1.88</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · select 2.61× the time of the fastest library (fully validating) way: structs (copy) twitter.json: 679 µs citm_catalog.json: 1,731 µs canada.json: 5,144 µs jeopardy.json: 239,164 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="409" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="282" text-anchor="middle">2.61</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · edit 2.89× the time of the fastest library (fully validating) twitter.json: 1,862 µs · borrowed (copy) citm_catalog.json: 4,194 µs · borrowed (copy) canada.json: 14,896 µs · owned (copy) jeopardy.json: 391,369 µs · borrowed (copy) (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="501" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="282" text-anchor="middle">2.89</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · minify 3.39× the time of the fastest library (fully validating) way: borrowed (copy) twitter.json: 1,889 µs citm_catalog.json: 4,196 µs canada.json: 15,716 µs jeopardy.json: 414,377 µs (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="593" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="282" text-anchor="middle">3.39</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="simd-json (Rust) · write 2.35× the time of the fastest library (fully validating) way: borrowed twitter.json: 582 µs citm_catalog.json: 800 µs canada.json: 5,147 µs jeopardy.json: 122,623 µs">
|
||||
<rect class="nj-heat-2" x="685" y="261" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="282" text-anchor="middle">2.35</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="318" text-anchor="end">serde_json (Rust)</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate 2.22× the time of the fastest library (fully validating) way: from_utf8 + IgnoredAny twitter.json: 624 µs citm_catalog.json: 1,440 µs canada.json: 2,406 µs jeopardy.json: 64,720 µs">
|
||||
<rect class="nj-heat-2" x="225" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="318" text-anchor="middle">2.22</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · validate, checking less 1.98× the time of the fastest fully validating library way: IgnoredAny twitter.json: 484 µs citm_catalog.json: 1,370 µs canada.json: 2,314 µs jeopardy.json: 58,247 µs trusts U​TF-8 in the strings it skips (from_slice); strings it reads are checked">
|
||||
<rect class="nj-heat-2" x="271" y="297" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="312" text-anchor="middle">1.98</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="325" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · sum 2.32× the time of the fastest library (fully validating) way: visitor twitter.json: 1,311 µs citm_catalog.json: 2,288 µs canada.json: 7,127 µs jeopardy.json: 129,497 µs">
|
||||
<rect class="nj-heat-2" x="317" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="318" text-anchor="middle">2.32</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · select 1.75× the time of the fastest library (fully validating) way: from_utf8 + structs twitter.json: 701 µs citm_catalog.json: 1,532 µs canada.json: 2,529 µs jeopardy.json: 107,316 µs">
|
||||
<rect class="nj-heat-2" x="409" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="318" text-anchor="middle">1.75</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · edit 4.55× the time of the fastest library (fully validating) way: Value twitter.json: 4,042 µs citm_catalog.json: 6,586 µs canada.json: 16,631 µs jeopardy.json: 632,766 µs">
|
||||
<rect class="nj-heat-3" x="501" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="318" text-anchor="middle">4.55</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · minify 4.94× the time of the fastest library (fully validating) way: Value twitter.json: 4,012 µs citm_catalog.json: 6,583 µs canada.json: 17,306 µs jeopardy.json: 509,702 µs">
|
||||
<rect class="nj-heat-3" x="593" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="318" text-anchor="middle">4.94</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="serde_json (Rust) · write 2.28× the time of the fastest library (fully validating) way: Value twitter.json: 550 µs citm_catalog.json: 887 µs canada.json: 4,005 µs jeopardy.json: 134,163 µs">
|
||||
<rect class="nj-heat-2" x="685" y="297" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="318" text-anchor="middle">2.28</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="354" text-anchor="end">Glaze</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · validate 2.21× the time of the fastest library (fully validating) way: validate_json twitter.json: 590 µs citm_catalog.json: 1,545 µs canada.json: 1,980 µs jeopardy.json: 76,009 µs">
|
||||
<rect class="nj-heat-2" x="225" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="354" text-anchor="middle">2.21</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · sum 4.04× the time of the fastest library (fully validating) way: generic (double, strict) twitter.json: 2,345 µs citm_catalog.json: 4,080 µs canada.json: 10,576 µs jeopardy.json: 250,685 µs">
|
||||
<rect class="nj-heat-3" x="317" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="354" text-anchor="middle">4.04</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select 1.44× the time of the fastest library (fully validating) way: structs (validate_skipped) twitter.json: 529 µs citm_catalog.json: 1,435 µs canada.json: 1,913 µs jeopardy.json: 91,253 µs">
|
||||
<rect class="nj-heat-1" x="409" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="354" text-anchor="middle">1.44</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · select, checking less 0.60× the time of the fastest fully validating library way: structs twitter.json: 342 µs citm_catalog.json: 410 µs canada.json: 431 µs jeopardy.json: 66,069 µs reads into structs and steps over fields it doesn't know without checking them (validate_skipped checks them too)">
|
||||
<rect class="nj-heat-0" x="455" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="348" text-anchor="middle">0.60</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="361" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · edit 4.85× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 3,525 µs citm_catalog.json: 6,551 µs canada.json: 23,644 µs jeopardy.json: 661,941 µs">
|
||||
<rect class="nj-heat-3" x="501" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="354" text-anchor="middle">4.85</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify 5.10× the time of the fastest library (fully validating) way: generic (strict) twitter.json: 3,780 µs citm_catalog.json: 6,416 µs canada.json: 23,765 µs jeopardy.json: 458,311 µs">
|
||||
<rect class="nj-heat-4" x="593" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="354" text-anchor="middle">5.10</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · minify, checking less 0.73× the time of the fastest fully validating library way: minify_json twitter.json: 422 µs citm_catalog.json: 1,144 µs canada.json: 2,350 µs jeopardy.json: 96,405 µs minify_json only removes whitespace, without parsing the values">
|
||||
<rect class="nj-heat-0" x="639" y="333" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="348" text-anchor="middle">0.73</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="361" text-anchor="middle">P</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="Glaze · write 1.84× the time of the fastest library (fully validating) twitter.json: 360 µs · generic citm_catalog.json: 660 µs · generic canada.json: 3,714 µs · generic (strict) jeopardy.json: 124,598 µs · generic">
|
||||
<rect class="nj-heat-2" x="685" y="333" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="354" text-anchor="middle">1.84</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel nj-charts-name-json" x="216" y="390" text-anchor="end">nlohmann/json json</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · validate 2.74× the time of the fastest library (fully validating) way: accept twitter.json: 677 µs citm_catalog.json: 1,433 µs canada.json: 4,584 µs jeopardy.json: 73,561 µs">
|
||||
<rect class="nj-heat-3" x="225" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="270" y="390" text-anchor="middle">2.74</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · sum 1.67× the time of the fastest library (fully validating) way: sax twitter.json: 797 µs citm_catalog.json: 1,548 µs canada.json: 6,004 µs jeopardy.json: 101,516 µs">
|
||||
<rect class="nj-heat-2" x="317" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="362" y="390" text-anchor="middle">1.67</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · select 7.24× the time of the fastest library (fully validating) way: structs (from_json) twitter.json: 3,325 µs citm_catalog.json: 5,126 µs canada.json: 11,908 µs jeopardy.json: 423,362 µs">
|
||||
<rect class="nj-heat-4" x="409" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="454" y="390" text-anchor="middle">7.24</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · edit 3.81× the time of the fastest library (fully validating) way: ordered_json twitter.json: 2,912 µs citm_catalog.json: 4,999 µs canada.json: 15,603 µs jeopardy.json: 604,744 µs">
|
||||
<rect class="nj-heat-3" x="501" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="546" y="390" text-anchor="middle">3.81</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · minify 4.79× the time of the fastest library (fully validating) way: parse + dump twitter.json: 4,143 µs citm_catalog.json: 5,702 µs canada.json: 16,463 µs jeopardy.json: 528,092 µs">
|
||||
<rect class="nj-heat-3" x="593" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="638" y="390" text-anchor="middle">4.79</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="nlohmann/json json · write 1.99× the time of the fastest library (fully validating) way: dump twitter.json: 471 µs citm_catalog.json: 644 µs canada.json: 4,344 µs jeopardy.json: 114,096 µs">
|
||||
<rect class="nj-heat-2" x="685" y="369" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="390" text-anchor="middle">1.99</text>
|
||||
</g>
|
||||
<text class="nj-charts-rowlabel " x="216" y="426" text-anchor="end">RapidJSON</text>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate 4.50× the time of the fastest library (fully validating) twitter.json: 1,552 µs · insitu (copy untimed) citm_catalog.json: 2,210 µs · insitu (copy untimed) canada.json: 4,104 µs · S​AX (string stream, default precision) jeopardy.json: 168,747 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="225" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="247.5" y="426" text-anchor="middle">4.50</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · validate, checking less 3.40× the time of the fastest fully validating library twitter.json: 1,082 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,570 µs · S​AX (default precision) (no encoding check) canada.json: 4,104 µs · S​AX (string stream, default precision) (validates fully) jeopardy.json: 110,856 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="271" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="292.5" y="420" text-anchor="middle">3.40</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="292.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum 2.98× the time of the fastest library (fully validating) twitter.json: 1,616 µs · insitu (copy untimed) citm_catalog.json: 2,290 µs · insitu (copy untimed) canada.json: 11,183 µs · S​AX (string stream) jeopardy.json: 181,500 µs · insitu (copy untimed)">
|
||||
<rect class="nj-heat-3" x="317" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="339.5" y="426" text-anchor="middle">2.98</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · sum, checking less 2.29× the time of the fastest fully validating library twitter.json: 1,130 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,743 µs · S​AX (no encoding check) canada.json: 11,109 µs · S​AX (string stream) (no encoding check) jeopardy.json: 119,706 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-2" x="363" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="384.5" y="420" text-anchor="middle">2.29</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="384.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select 3.84× the time of the fastest library (fully validating) way: insitu (copy untimed) twitter.json: 1,560 µs citm_catalog.json: 2,127 µs canada.json: 11,547 µs jeopardy.json: 176,066 µs">
|
||||
<rect class="nj-heat-3" x="409" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="431.5" y="426" text-anchor="middle">3.84</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · select, checking less 3.06× the time of the fastest fully validating library twitter.json: 1,079 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 1,817 µs · insitu (copy untimed) (no encoding check) canada.json: 11,436 µs · Document (string stream) (no encoding check) jeopardy.json: 122,354 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="455" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="476.5" y="420" text-anchor="middle">3.06</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="476.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit 2.92× the time of the fastest library (fully validating) twitter.json: 2,333 µs · insitu (copy untimed) citm_catalog.json: 3,133 µs · insitu (copy untimed) canada.json: 20,518 µs · insitu (copy) jeopardy.json: 315,892 µs · insitu (copy untimed) (copy): parses in place, on a copy of the input that is part of the time">
|
||||
<rect class="nj-heat-3" x="501" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="523.5" y="426" text-anchor="middle">2.92</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · edit, checking less 2.58× the time of the fastest fully validating library twitter.json: 1,838 µs · insitu (copy untimed) (no encoding check) citm_catalog.json: 2,836 µs · insitu (copy untimed) (no encoding check) canada.json: 20,320 µs · Document (string stream) (no encoding check) jeopardy.json: 271,888 µs · insitu (copy untimed) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)">
|
||||
<rect class="nj-heat-3" x="547" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="568.5" y="420" text-anchor="middle">2.58</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="568.5" y="433" text-anchor="middle">U</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify 3.64× the time of the fastest library (fully validating) twitter.json: 3,015 µs · S​AX to Writer citm_catalog.json: 3,012 µs · S​AX to Writer canada.json: 21,177 µs · Document + Writer jeopardy.json: 355,727 µs · S​AX to Writer (string stream)">
|
||||
<rect class="nj-heat-3" x="593" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="615.5" y="426" text-anchor="middle">3.64</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · minify, checking less 2.64× the time of the fastest fully validating library twitter.json: 1,978 µs · S​AX to Writer (no encoding check) citm_catalog.json: 2,493 µs · S​AX to Writer (no encoding check) canada.json: 15,512 µs · S​AX to Writer (raw numbers) (no encoding check) jeopardy.json: 249,235 µs · S​AX to Writer (string stream) (no encoding check) trusts U​TF-8: RapidJSON's default (kParseValidateEncodingFlag checks it) copies each number's text instead of formatting it (kParseNumbersAsStringsFlag)">
|
||||
<rect class="nj-heat-3" x="639" y="405" width="44" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="660.5" y="420" text-anchor="middle">2.64</text>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="660.5" y="433" text-anchor="middle">U N</text>
|
||||
</g>
|
||||
<g class="nj-heat-cell" tabindex="0" data-tip="RapidJSON · write 3.11× the time of the fastest library (fully validating) way: Writer twitter.json: 717 µs citm_catalog.json: 1,033 µs canada.json: 9,017 µs jeopardy.json: 134,260 µs">
|
||||
<rect class="nj-heat-3" x="685" y="405" width="90" height="34" rx="3"/>
|
||||
<text class="nj-charts-cell" x="730" y="426" text-anchor="middle">3.11</text>
|
||||
</g>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="472">time relative to the fastest fully validating library, less is better</text>
|
||||
<g><rect class="nj-heat-0" x="8" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="46" y="496" text-anchor="middle">below 1.15</text></g>
|
||||
<g><rect class="nj-heat-1" x="88" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="126" y="496" text-anchor="middle">1.15 to 1.5</text></g>
|
||||
<g><rect class="nj-heat-2" x="168" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="206" y="496" text-anchor="middle">1.5 to 2.5</text></g>
|
||||
<g><rect class="nj-heat-3" x="248" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="286" y="496" text-anchor="middle">2.5 to 5</text></g>
|
||||
<g><rect class="nj-heat-4" x="328" y="482" width="76" height="20" rx="3"/>
|
||||
<text class="nj-charts-cell nj-charts-cell--small" x="366" y="496" text-anchor="middle">5 and more</text></g>
|
||||
<rect class="nj-heat-na" x="420" y="482" width="40" height="20" rx="3"/>
|
||||
<text class="nj-charts-tick" x="440" y="496">n/a</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="468" y="496">no A​PI for it</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 45 KiB |
@@ -1,26 +1,31 @@
|
||||
<svg class="nj-fig nj-exceptions-qa nj-exceptions-qa--wide" viewBox="0 0 760 808" role="img" aria-labelledby="nj-qa-title-w nj-qa-desc-w" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="nj-fig nj-exceptions-qa nj-exceptions-qa--wide" viewBox="0 0 760 862" role="img" aria-labelledby="nj-qa-title-w nj-qa-desc-w" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-qa-title-w">Quality assurance pipeline</title>
|
||||
<desc id="nj-qa-desc-w">Every push or pull request starts these checks in parallel: Build matrix (every push / PR): 50+ compilers: G​CC, Clang, M​SVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G​CC 300+ warnings; Unit tests (doctest) (every push / PR): every public A​PI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (every push / PR): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I​WYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Dynamic analysis (every push / PR): runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C​I cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R​EUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open.</desc>
|
||||
<desc id="nj-qa-desc-w">A push or pull request starts these checks; the badges say when each runs: Build matrix (every push / PR, before merge): 50+ compilers: G​CC, Clang, M​SVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G​CC 300+ warnings a subset on every push and PR, all before merge; Intel, NVIDIA, C​UDA, and ARM64 nightly; Unit tests (doctest) (every push / PR): every public A​PI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (nightly): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I​WYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Infer nightly; Dynamic analysis (every push / PR, nightly): runtime assertions Valgrind (Memcheck), nightly address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C​I cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R​EUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open.</desc>
|
||||
<defs><marker id="nj-qa-arrow-w" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path class="fg-head" d="M0 1 L10 5 L0 9 z"/></marker></defs>
|
||||
<rect class="nj-exceptions-groupbox" x="12" y="70" width="736" height="594" rx="12"/>
|
||||
<rect class="nj-exceptions-groupbox" x="12" y="70" width="736" height="648" rx="12"/>
|
||||
<rect class="nj-exceptions-stage" x="265" y="8" width="230" height="34" rx="17"/>
|
||||
<text class="nj-exceptions-stagetext" x="380" y="30">push or pull request</text>
|
||||
<line class="nj-exceptions-edge" x1="380" y1="42" x2="380" y2="68" marker-end="url(#nj-qa-arrow-w)"/>
|
||||
<text class="nj-exceptions-group" x="26" y="94">checks, run in parallel on GitHub Actions and AppVeyor</text>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="110" width="228" height="184" rx="8"/>
|
||||
<rect class="nj-exceptions-box" x="26" y="110" width="228" height="238" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="135">Build matrix</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="146" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="160">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="156.5" y="146" width="91.6" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="202.3" y="160">before merge</text>
|
||||
<text class="nj-exceptions-line" x="40" y="188">50+ compilers: G​CC, Clang, M​SVC,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="206">AppleClang, Intel, NVIDIA, ...</text>
|
||||
<text class="nj-exceptions-line" x="40" y="224">C++11, 14, 17, 20, 23, and 26</text>
|
||||
<text class="nj-exceptions-line" x="40" y="242">libc++ and libstdc++</text>
|
||||
<text class="nj-exceptions-line" x="40" y="260">warnings: Clang -Weverything,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="278">G​CC 300+ warnings</text>
|
||||
<text class="nj-exceptions-line" x="40" y="296">a subset on every push and PR,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="314">all before merge; Intel, NVIDIA,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="332">C​UDA, and ARM64 nightly</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="266" y="110" width="228" height="184" rx="8"/>
|
||||
<rect class="nj-exceptions-box" x="266" y="110" width="228" height="238" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="280" y="135">Unit tests (doctest)</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="280" y="146" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="335.25" y="160">every push / PR</text>
|
||||
@@ -32,209 +37,218 @@
|
||||
<text class="nj-exceptions-line" x="280" y="278">and object types</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="506" y="110" width="228" height="184" rx="8"/>
|
||||
<rect class="nj-exceptions-box" x="506" y="110" width="228" height="238" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="520" y="135">Coverage</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="520" y="146" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="575.25" y="160">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="520" y="146" width="60.1" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="550.05" y="160">nightly</text>
|
||||
<text class="nj-exceptions-line" x="520" y="188">unit tests cover all lines</text>
|
||||
<text class="nj-exceptions-line" x="520" y="206">of the code base</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="306" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="331">Static analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="342" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="356">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="342" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="356">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="384">Clang-Tidy, Cppcheck, Infer</text>
|
||||
<text class="nj-exceptions-line" x="40" y="402">Clang Static Analyzer (52</text>
|
||||
<text class="nj-exceptions-line" x="40" y="420">checkers), I​WYU, Codacy</text>
|
||||
<text class="nj-exceptions-line" x="40" y="438">CodeQL, Semgrep, Flawfinder</text>
|
||||
<text class="nj-exceptions-line" x="40" y="456">(also scheduled)</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="360" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="385">Static analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="396" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="410">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="396" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="410">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="438">Clang-Tidy, Cppcheck, Infer</text>
|
||||
<text class="nj-exceptions-line" x="40" y="456">Clang Static Analyzer (52</text>
|
||||
<text class="nj-exceptions-line" x="40" y="474">checkers), I​WYU, Codacy</text>
|
||||
<text class="nj-exceptions-line" x="40" y="492">CodeQL, Semgrep, Flawfinder</text>
|
||||
<text class="nj-exceptions-line" x="40" y="510">(also scheduled); Infer nightly</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="266" y="306" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="280" y="331">Dynamic analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="280" y="342" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="335.25" y="356">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="280" y="384">runtime assertions</text>
|
||||
<text class="nj-exceptions-line" x="280" y="402">Valgrind (Memcheck)</text>
|
||||
<text class="nj-exceptions-line" x="280" y="420">address and undefined behavior</text>
|
||||
<text class="nj-exceptions-line" x="280" y="438">sanitizers, integer overflow,</text>
|
||||
<text class="nj-exceptions-line" x="280" y="456">nullability violations</text>
|
||||
<rect class="nj-exceptions-box" x="266" y="360" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="280" y="385">Dynamic analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="280" y="396" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="335.25" y="410">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="396.5" y="396" width="60.1" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="426.55" y="410">nightly</text>
|
||||
<text class="nj-exceptions-line" x="280" y="438">runtime assertions</text>
|
||||
<text class="nj-exceptions-line" x="280" y="456">Valgrind (Memcheck), nightly</text>
|
||||
<text class="nj-exceptions-line" x="280" y="474">address and undefined behavior</text>
|
||||
<text class="nj-exceptions-line" x="280" y="492">sanitizers, integer overflow,</text>
|
||||
<text class="nj-exceptions-line" x="280" y="510">nullability violations</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="506" y="306" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="520" y="331">Fuzzing</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="520" y="342" width="66.4" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="553.2" y="356">every PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--cont" x="592.4" y="342" width="79" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--cont" x="631.9" y="356">continuous</text>
|
||||
<text class="nj-exceptions-line" x="520" y="384">CIFuzz on every pull request</text>
|
||||
<text class="nj-exceptions-line" x="520" y="402">OSS-Fuzz: billions of inputs</text>
|
||||
<text class="nj-exceptions-line" x="520" y="420">every crash fixed with a</text>
|
||||
<text class="nj-exceptions-line" x="520" y="438">reproducing unit test</text>
|
||||
<rect class="nj-exceptions-box" x="506" y="360" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="520" y="385">Fuzzing</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="520" y="396" width="66.4" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="553.2" y="410">every PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--cont" x="592.4" y="396" width="79" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--cont" x="631.9" y="410">continuous</text>
|
||||
<text class="nj-exceptions-line" x="520" y="438">CIFuzz on every pull request</text>
|
||||
<text class="nj-exceptions-line" x="520" y="456">OSS-Fuzz: billions of inputs</text>
|
||||
<text class="nj-exceptions-line" x="520" y="474">every crash fixed with a</text>
|
||||
<text class="nj-exceptions-line" x="520" y="492">reproducing unit test</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="484" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="509">Style</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="520" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="534">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="562">Artistic Style (astyle),</text>
|
||||
<text class="nj-exceptions-line" x="40" y="580">enforced in the C​I</text>
|
||||
<text class="nj-exceptions-line" x="40" y="598">cpplint with 61 rules</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="538" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="563">Style</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="574" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="588">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="616">Artistic Style (astyle),</text>
|
||||
<text class="nj-exceptions-line" x="40" y="634">enforced in the C​I</text>
|
||||
<text class="nj-exceptions-line" x="40" y="652">cpplint with 61 rules</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="266" y="484" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="280" y="509">Docs and examples</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="280" y="520" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="335.25" y="534">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="396.5" y="520" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="432.85" y="534">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="280" y="562">every documentation example is</text>
|
||||
<text class="nj-exceptions-line" x="280" y="580">tested; changed output fails</text>
|
||||
<text class="nj-exceptions-line" x="280" y="598">site built with warnings</text>
|
||||
<text class="nj-exceptions-line" x="280" y="616">as errors; links checked</text>
|
||||
<text class="nj-exceptions-line" x="280" y="634">regularly (scheduled)</text>
|
||||
<rect class="nj-exceptions-box" x="266" y="538" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="280" y="563">Docs and examples</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="280" y="574" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="335.25" y="588">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="396.5" y="574" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="432.85" y="588">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="280" y="616">every documentation example is</text>
|
||||
<text class="nj-exceptions-line" x="280" y="634">tested; changed output fails</text>
|
||||
<text class="nj-exceptions-line" x="280" y="652">site built with warnings</text>
|
||||
<text class="nj-exceptions-line" x="280" y="670">as errors; links checked</text>
|
||||
<text class="nj-exceptions-line" x="280" y="688">regularly (scheduled)</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="506" y="484" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="520" y="509">Integration, supply chain</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="520" y="520" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="575.25" y="534">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="636.5" y="520" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="672.85" y="534">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="520" y="562">CMake 3.5, 3.31.6, and 4.0.0</text>
|
||||
<text class="nj-exceptions-line" x="520" y="580">Meson, Swift Package Manager</text>
|
||||
<text class="nj-exceptions-line" x="520" y="598">dependency review on every PR</text>
|
||||
<text class="nj-exceptions-line" x="520" y="616">Dependabot daily, OpenSSF</text>
|
||||
<text class="nj-exceptions-line" x="520" y="634">Scorecard, R​EUSE</text>
|
||||
<rect class="nj-exceptions-box" x="506" y="538" width="228" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="520" y="563">Integration, supply chain</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="520" y="574" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="575.25" y="588">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="636.5" y="574" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="672.85" y="588">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="520" y="616">CMake 3.5, 3.31.6, and 4.0.0</text>
|
||||
<text class="nj-exceptions-line" x="520" y="634">Meson, Swift Package Manager</text>
|
||||
<text class="nj-exceptions-line" x="520" y="652">dependency review on every PR</text>
|
||||
<text class="nj-exceptions-line" x="520" y="670">Dependabot daily, OpenSSF</text>
|
||||
<text class="nj-exceptions-line" x="520" y="688">Scorecard, R​EUSE</text>
|
||||
</g>
|
||||
<line class="nj-exceptions-edge" x1="380" y1="664" x2="380" y2="690" marker-end="url(#nj-qa-arrow-w)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="265" y="692" width="230" height="34" rx="17"/>
|
||||
<text class="nj-exceptions-stagetext" x="380" y="714">merge into develop</text>
|
||||
<line class="nj-exceptions-edge" x1="380" y1="726" x2="380" y2="752" marker-end="url(#nj-qa-arrow-w)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="230" y="754" width="300" height="46" rx="23"/>
|
||||
<text class="nj-exceptions-stagetext" x="380" y="776">release</text>
|
||||
<text class="nj-exceptions-stagesub" x="380" y="792">no open vulnerability alert</text>
|
||||
<line class="nj-exceptions-edge" x1="380" y1="718" x2="380" y2="744" marker-end="url(#nj-qa-arrow-w)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="265" y="746" width="230" height="34" rx="17"/>
|
||||
<text class="nj-exceptions-stagetext" x="380" y="768">merge into develop</text>
|
||||
<line class="nj-exceptions-edge" x1="380" y1="780" x2="380" y2="806" marker-end="url(#nj-qa-arrow-w)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="230" y="808" width="300" height="46" rx="23"/>
|
||||
<text class="nj-exceptions-stagetext" x="380" y="830">release</text>
|
||||
<text class="nj-exceptions-stagesub" x="380" y="846">no open vulnerability alert</text>
|
||||
</svg>
|
||||
<svg class="nj-fig nj-exceptions-qa nj-exceptions-qa--narrow" viewBox="0 0 360 1786" role="img" aria-labelledby="nj-qa-title-n nj-qa-desc-n" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="nj-fig nj-exceptions-qa nj-exceptions-qa--narrow" viewBox="0 0 360 1840" role="img" aria-labelledby="nj-qa-title-n nj-qa-desc-n" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-qa-title-n">Quality assurance pipeline</title>
|
||||
<desc id="nj-qa-desc-n">Every push or pull request starts these checks in parallel: Build matrix (every push / PR): 50+ compilers: G​CC, Clang, M​SVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G​CC 300+ warnings; Unit tests (doctest) (every push / PR): every public A​PI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (every push / PR): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I​WYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Dynamic analysis (every push / PR): runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C​I cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R​EUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open.</desc>
|
||||
<desc id="nj-qa-desc-n">A push or pull request starts these checks; the badges say when each runs: Build matrix (every push / PR, before merge): 50+ compilers: G​CC, Clang, M​SVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G​CC 300+ warnings a subset on every push and PR, all before merge; Intel, NVIDIA, C​UDA, and ARM64 nightly; Unit tests (doctest) (every push / PR): every public A​PI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (nightly): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I​WYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Infer nightly; Dynamic analysis (every push / PR, nightly): runtime assertions Valgrind (Memcheck), nightly address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C​I cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R​EUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open.</desc>
|
||||
<defs><marker id="nj-qa-arrow-n" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path class="fg-head" d="M0 1 L10 5 L0 9 z"/></marker></defs>
|
||||
<rect class="nj-exceptions-groupbox" x="12" y="70" width="336" height="1572" rx="12"/>
|
||||
<rect class="nj-exceptions-groupbox" x="12" y="70" width="336" height="1626" rx="12"/>
|
||||
<rect class="nj-exceptions-stage" x="65" y="8" width="230" height="34" rx="17"/>
|
||||
<text class="nj-exceptions-stagetext" x="180" y="30">push or pull request</text>
|
||||
<line class="nj-exceptions-edge" x1="180" y1="42" x2="180" y2="68" marker-end="url(#nj-qa-arrow-n)"/>
|
||||
<text class="nj-exceptions-group" x="26" y="94">checks, run in parallel</text>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="110" width="308" height="184" rx="8"/>
|
||||
<rect class="nj-exceptions-box" x="26" y="110" width="308" height="238" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="135">Build matrix</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="146" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="160">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="156.5" y="146" width="91.6" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="202.3" y="160">before merge</text>
|
||||
<text class="nj-exceptions-line" x="40" y="188">50+ compilers: G​CC, Clang, M​SVC,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="206">AppleClang, Intel, NVIDIA, ...</text>
|
||||
<text class="nj-exceptions-line" x="40" y="224">C++11, 14, 17, 20, 23, and 26</text>
|
||||
<text class="nj-exceptions-line" x="40" y="242">libc++ and libstdc++</text>
|
||||
<text class="nj-exceptions-line" x="40" y="260">warnings: Clang -Weverything,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="278">G​CC 300+ warnings</text>
|
||||
<text class="nj-exceptions-line" x="40" y="296">a subset on every push and PR,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="314">all before merge; Intel, NVIDIA,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="332">C​UDA, and ARM64 nightly</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="306" width="308" height="184" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="331">Unit tests (doctest)</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="342" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="356">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="384">every public A​PI function</text>
|
||||
<text class="nj-exceptions-line" x="40" y="402">every exception id and message</text>
|
||||
<text class="nj-exceptions-line" x="40" y="420">all Unicode code points</text>
|
||||
<text class="nj-exceptions-line" x="40" y="438">single header and split headers</text>
|
||||
<text class="nj-exceptions-line" x="40" y="456">custom number, string, array,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="474">and object types</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="360" width="308" height="184" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="385">Unit tests (doctest)</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="396" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="410">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="438">every public A​PI function</text>
|
||||
<text class="nj-exceptions-line" x="40" y="456">every exception id and message</text>
|
||||
<text class="nj-exceptions-line" x="40" y="474">all Unicode code points</text>
|
||||
<text class="nj-exceptions-line" x="40" y="492">single header and split headers</text>
|
||||
<text class="nj-exceptions-line" x="40" y="510">custom number, string, array,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="528">and object types</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="502" width="308" height="112" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="527">Coverage</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="538" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="552">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="580">unit tests cover all lines</text>
|
||||
<text class="nj-exceptions-line" x="40" y="598">of the code base</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="556" width="308" height="112" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="581">Coverage</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="40" y="592" width="60.1" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="70.05" y="606">nightly</text>
|
||||
<text class="nj-exceptions-line" x="40" y="634">unit tests cover all lines</text>
|
||||
<text class="nj-exceptions-line" x="40" y="652">of the code base</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="626" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="651">Static analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="662" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="676">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="662" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="676">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="704">Clang-Tidy, Cppcheck, Infer</text>
|
||||
<text class="nj-exceptions-line" x="40" y="722">Clang Static Analyzer (52</text>
|
||||
<text class="nj-exceptions-line" x="40" y="740">checkers), I​WYU, Codacy</text>
|
||||
<text class="nj-exceptions-line" x="40" y="758">CodeQL, Semgrep, Flawfinder</text>
|
||||
<text class="nj-exceptions-line" x="40" y="776">(also scheduled)</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="680" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="705">Static analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="716" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="730">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="716" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="730">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="758">Clang-Tidy, Cppcheck, Infer</text>
|
||||
<text class="nj-exceptions-line" x="40" y="776">Clang Static Analyzer (52</text>
|
||||
<text class="nj-exceptions-line" x="40" y="794">checkers), I​WYU, Codacy</text>
|
||||
<text class="nj-exceptions-line" x="40" y="812">CodeQL, Semgrep, Flawfinder</text>
|
||||
<text class="nj-exceptions-line" x="40" y="830">(also scheduled); Infer nightly</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="804" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="829">Dynamic analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="840" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="854">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="882">runtime assertions</text>
|
||||
<text class="nj-exceptions-line" x="40" y="900">Valgrind (Memcheck)</text>
|
||||
<text class="nj-exceptions-line" x="40" y="918">address and undefined behavior</text>
|
||||
<text class="nj-exceptions-line" x="40" y="936">sanitizers, integer overflow,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="954">nullability violations</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="858" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="883">Dynamic analysis</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="894" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="908">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="894" width="60.1" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="186.55" y="908">nightly</text>
|
||||
<text class="nj-exceptions-line" x="40" y="936">runtime assertions</text>
|
||||
<text class="nj-exceptions-line" x="40" y="954">Valgrind (Memcheck), nightly</text>
|
||||
<text class="nj-exceptions-line" x="40" y="972">address and undefined behavior</text>
|
||||
<text class="nj-exceptions-line" x="40" y="990">sanitizers, integer overflow,</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1008">nullability violations</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="982" width="308" height="148" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1007">Fuzzing</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1018" width="66.4" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="73.2" y="1032">every PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--cont" x="112.4" y="1018" width="79" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--cont" x="151.9" y="1032">continuous</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1060">CIFuzz on every pull request</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1078">OSS-Fuzz: billions of inputs</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1096">every crash fixed with a</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1114">reproducing unit test</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="1036" width="308" height="148" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1061">Fuzzing</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1072" width="66.4" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="73.2" y="1086">every PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--cont" x="112.4" y="1072" width="79" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--cont" x="151.9" y="1086">continuous</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1114">CIFuzz on every pull request</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1132">OSS-Fuzz: billions of inputs</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1150">every crash fixed with a</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1168">reproducing unit test</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="1142" width="308" height="130" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1167">Style</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1178" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="1192">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1220">Artistic Style (astyle),</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1238">enforced in the C​I</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1256">cpplint with 61 rules</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="1196" width="308" height="130" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1221">Style</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1232" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="1246">every push / PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1274">Artistic Style (astyle),</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1292">enforced in the C​I</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1310">cpplint with 61 rules</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="1284" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1309">Docs and examples</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1320" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="1334">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="1320" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="1334">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1362">every documentation example is</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1380">tested; changed output fails</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1398">site built with warnings</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1416">as errors; links checked</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1434">regularly (scheduled)</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="1338" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1363">Docs and examples</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1374" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="1388">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="1374" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="1388">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1416">every documentation example is</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1434">tested; changed output fails</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1452">site built with warnings</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1470">as errors; links checked</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1488">regularly (scheduled)</text>
|
||||
</g>
|
||||
<g class="nj-exceptions-card">
|
||||
<rect class="nj-exceptions-box" x="26" y="1462" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1487">Integration, supply chain</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1498" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="1512">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="1498" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="1512">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1540">CMake 3.5, 3.31.6, and 4.0.0</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1558">Meson, Swift Package Manager</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1576">dependency review on every PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1594">Dependabot daily, OpenSSF</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1612">Scorecard, R​EUSE</text>
|
||||
<rect class="nj-exceptions-box" x="26" y="1516" width="308" height="166" rx="8"/>
|
||||
<text class="nj-exceptions-ctitle" x="40" y="1541">Integration, supply chain</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--push" x="40" y="1552" width="110.5" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--push" x="95.25" y="1566">every push / PR</text>
|
||||
<rect class="nj-exceptions-badge nj-exceptions-badge--sched" x="156.5" y="1552" width="72.7" height="20" rx="10"/>
|
||||
<text class="nj-exceptions-badgetext nj-exceptions-badgetext--sched" x="192.85" y="1566">scheduled</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1594">CMake 3.5, 3.31.6, and 4.0.0</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1612">Meson, Swift Package Manager</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1630">dependency review on every PR</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1648">Dependabot daily, OpenSSF</text>
|
||||
<text class="nj-exceptions-line" x="40" y="1666">Scorecard, R​EUSE</text>
|
||||
</g>
|
||||
<line class="nj-exceptions-edge" x1="180" y1="1642" x2="180" y2="1668" marker-end="url(#nj-qa-arrow-n)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="65" y="1670" width="230" height="34" rx="17"/>
|
||||
<text class="nj-exceptions-stagetext" x="180" y="1692">merge into develop</text>
|
||||
<line class="nj-exceptions-edge" x1="180" y1="1704" x2="180" y2="1730" marker-end="url(#nj-qa-arrow-n)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="30" y="1732" width="300" height="46" rx="23"/>
|
||||
<text class="nj-exceptions-stagetext" x="180" y="1754">release</text>
|
||||
<text class="nj-exceptions-stagesub" x="180" y="1770">no open vulnerability alert</text>
|
||||
<line class="nj-exceptions-edge" x1="180" y1="1696" x2="180" y2="1722" marker-end="url(#nj-qa-arrow-n)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="65" y="1724" width="230" height="34" rx="17"/>
|
||||
<text class="nj-exceptions-stagetext" x="180" y="1746">merge into develop</text>
|
||||
<line class="nj-exceptions-edge" x1="180" y1="1758" x2="180" y2="1784" marker-end="url(#nj-qa-arrow-n)"/>
|
||||
<rect class="nj-exceptions-stage nj-exceptions-stage--merge" x="30" y="1786" width="300" height="46" rx="23"/>
|
||||
<text class="nj-exceptions-stagetext" x="180" y="1808">release</text>
|
||||
<text class="nj-exceptions-stagesub" x="180" y="1824">no open vulnerability alert</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
* Marks links that leave the site with the class "nj-external", which brand.css turns into a small icon in front of
|
||||
* the link. A link is external when its host is neither the current one nor the production site. Links in the page
|
||||
* actions (edit, raw), buttons, header anchors, a blog post's byline, and links that only wrap an image (badges) are
|
||||
* left alone.
|
||||
* actions (edit, raw), buttons, header anchors, and links that only wrap an image (badges) are left alone.
|
||||
* Runs through Material's document$ (navigation.instant), so it also applies after an instant page switch.
|
||||
*/
|
||||
(function () {
|
||||
@@ -18,7 +17,7 @@
|
||||
if (a.protocol !== "http:" && a.protocol !== "https:") {
|
||||
continue;
|
||||
}
|
||||
if (a.matches(".md-button, .md-content__button, .headerlink, .nj-byline a") || a.querySelector("img, svg")) {
|
||||
if (a.matches(".md-button, .md-content__button, .headerlink") || a.querySelector("img, svg")) {
|
||||
continue;
|
||||
}
|
||||
a.classList.add("nj-external");
|
||||
|
||||
@@ -104,72 +104,3 @@
|
||||
init();
|
||||
}
|
||||
})();
|
||||
|
||||
/* figures: the tooltips of the heatmaps in home/blog/how_3_13_0_got_faster.md (perf_blog_usecases_*.svg). Each
|
||||
cell is a focusable <g data-tip>: its lines (the first one the heading) are shown on hover, keyboard focus or tap.
|
||||
Without JS, the figure's <desc> and the tables in the appendix carry the same numbers. */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var tip = null;
|
||||
var current = null;
|
||||
|
||||
function show(cell) {
|
||||
if (!tip) {
|
||||
tip = document.createElement("div");
|
||||
tip.className = "nj-heat-tip";
|
||||
tip.setAttribute("role", "tooltip");
|
||||
tip.hidden = true;
|
||||
document.body.appendChild(tip);
|
||||
}
|
||||
if (current) current.classList.remove("nj-heat-on");
|
||||
current = cell;
|
||||
cell.classList.add("nj-heat-on");
|
||||
var lines = (cell.getAttribute("data-tip") || "").split("\n");
|
||||
tip.textContent = "";
|
||||
lines.forEach(function (line, i) {
|
||||
var el = document.createElement(i === 0 ? "strong" : "div");
|
||||
el.textContent = line;
|
||||
tip.appendChild(el);
|
||||
});
|
||||
tip.hidden = false;
|
||||
var r = cell.getBoundingClientRect();
|
||||
var w = tip.offsetWidth, h = tip.offsetHeight;
|
||||
var x = Math.min(Math.max(8, r.left + r.width / 2 - w / 2), document.documentElement.clientWidth - w - 8);
|
||||
var y = r.bottom + 8 + h > window.innerHeight ? r.top - h - 8 : r.bottom + 8;
|
||||
tip.style.left = (x + window.scrollX) + "px";
|
||||
tip.style.top = (y + window.scrollY) + "px";
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (current) current.classList.remove("nj-heat-on");
|
||||
current = null;
|
||||
if (tip) tip.hidden = true;
|
||||
}
|
||||
|
||||
function init() {
|
||||
hide();
|
||||
Array.prototype.forEach.call(document.querySelectorAll("svg.nj-charts--heat .nj-heat-cell"), function (cell) {
|
||||
if (cell.dataset.njHeatReady) return;
|
||||
cell.dataset.njHeatReady = "1";
|
||||
cell.addEventListener("mouseenter", function () { show(cell); });
|
||||
cell.addEventListener("mouseleave", hide);
|
||||
cell.addEventListener("focus", function () { show(cell); });
|
||||
cell.addEventListener("blur", hide);
|
||||
// a tap also focuses the cell; a tap elsewhere or Escape hides the tooltip
|
||||
cell.addEventListener("click", function (ev) { ev.stopPropagation(); show(cell); });
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("click", hide);
|
||||
document.addEventListener("keydown", function (ev) { if (ev.key === "Escape") hide(); });
|
||||
window.addEventListener("scroll", hide, { passive: true });
|
||||
|
||||
if (typeof document$ !== "undefined" && document$ && typeof document$.subscribe === "function") {
|
||||
document$.subscribe(init);
|
||||
} else if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -8,7 +8,6 @@
|
||||
*[BDFL]: Benevolent Dictator for Life
|
||||
*[BJData]: Binary JData
|
||||
*[BON8]: Binary Object Notation 8
|
||||
*[BSL]: Boost Software License
|
||||
*[BSON]: Binary JSON
|
||||
*[CBOR]: Concise Binary Object Representation
|
||||
*[CC0]: Creative Commons Zero
|
||||
@@ -17,7 +16,6 @@
|
||||
*[CUDA]: Compute Unified Device Architecture
|
||||
*[CVE]: Common Vulnerabilities and Exposures
|
||||
*[DOM]: Document Object Model
|
||||
*[EDG]: Edison Design Group, maker of a C++ compiler front end
|
||||
*[EOF]: End of File
|
||||
*[FAQ]: Frequently Asked Questions
|
||||
*[GCC]: GNU Compiler Collection
|
||||
@@ -33,11 +31,9 @@
|
||||
*[JSONC]: JSON with Comments
|
||||
*[JWCC]: JSON With Commas and Comments
|
||||
*[LLDB]: LLVM Debugger
|
||||
*[LTO]: Link-Time Optimization
|
||||
*[LTS]: Long-Term Support
|
||||
*[MinGW]: Minimalist GNU for Windows
|
||||
*[MIT]: Massachusetts Institute of Technology
|
||||
*[MPL]: Mozilla Public License
|
||||
*[MsgPack]: MessagePack
|
||||
*[MSVC]: Microsoft Visual C++
|
||||
*[NaN]: Not a Number
|
||||
@@ -46,7 +42,6 @@
|
||||
*[NEON]: Arm SIMD instruction set extension
|
||||
*[NUL]: Null character (U+0000, byte value 0)
|
||||
*[ODR]: One Definition Rule
|
||||
*[PCH]: Precompiled Header
|
||||
*[REUSE]: Software licensing specification by the Free Software Foundation Europe
|
||||
*[RFC]: Request for Comments
|
||||
*[RTTI]: Runtime Type Information
|
||||
@@ -65,4 +60,3 @@
|
||||
*[UDLs]: User-defined literals
|
||||
*[URL]: Uniform Resource Locator
|
||||
*[UTF]: Unicode Transformation Format
|
||||
*[XOR]: Exclusive or
|
||||
@@ -104,8 +104,6 @@ nav:
|
||||
- 'v2.0.0': home/releases/v2.0.0.md
|
||||
- 'v1.1.0': home/releases/v1.1.0.md
|
||||
- 'v1.0.0': home/releases/v1.0.0.md
|
||||
- Blog:
|
||||
- 'How 3.13.0 got faster': home/blog/how_3_13_0_got_faster.md
|
||||
- home/design_goals.md
|
||||
- home/architecture.md
|
||||
- home/customers.md
|
||||
@@ -611,7 +609,6 @@ plugins:
|
||||
Home:
|
||||
- index.md
|
||||
- home/*.md
|
||||
- home/blog/*.md
|
||||
Features:
|
||||
- features/*.md
|
||||
- features/binary_formats/*.md
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
benchmark,unit,3.12.0,3.13.0,speedup
|
||||
Accept/canada,ns,1.29488e+07,2.3494e+06,5.512
|
||||
Accept/citm_catalog,ns,6.53091e+06,923408,7.073
|
||||
Accept/floats,ns,1.15702e+08,2.26771e+07,5.102
|
||||
Accept/jeopardy,ns,2.20758e+08,5.92935e+07,3.723
|
||||
Accept/signed_ints,ns,1.17358e+08,2.82947e+07,4.148
|
||||
Accept/small_signed_ints,ns,5.75113e+07,1.80352e+07,3.189
|
||||
Accept/twitter,ns,2.51345e+06,483792,5.195
|
||||
Accept/unsigned_ints,ns,1.16297e+08,2.97181e+07,3.913
|
||||
BinaryToCbor/1024,ns,298.444,107.095,2.787
|
||||
BinaryToCbor/128,ns,248.661,116.711,2.131
|
||||
BinaryToCbor/16,ns,244.687,49.6325,4.930
|
||||
BinaryToCbor/16384,ns,952.115,413.62,2.302
|
||||
BinaryToCbor/2048,ns,328.419,125.183,2.624
|
||||
BinaryToCbor/256,ns,264.678,90.8937,2.912
|
||||
BinaryToCbor/32,ns,251.632,50.4059,4.992
|
||||
BinaryToCbor/32768,ns,1541.05,802.721,1.920
|
||||
BinaryToCbor/4096,ns,406.957,177.412,2.294
|
||||
BinaryToCbor/512,ns,289.876,102.063,2.840
|
||||
BinaryToCbor/64,ns,254.928,84.6434,3.012
|
||||
BinaryToCbor/8,ns,247.618,49.3761,5.015
|
||||
BinaryToCbor/8192,ns,514.281,256.456,2.005
|
||||
Copy/canada,ns,3.78116e+06,2.92734e+06,1.292
|
||||
Copy/citm_catalog,ns,1.7026e+06,1.51108e+06,1.127
|
||||
Copy/twitter,ns,840201,767400,1.095
|
||||
CopyAssign/canada,ns,3.86416e+06,2.94449e+06,1.312
|
||||
CopyAssign/citm_catalog,ns,1.76529e+06,1.58608e+06,1.113
|
||||
CopyAssign/twitter,ns,884985,790724,1.119
|
||||
CopyOnly/canada,ns,1.60229e+06,1.57507e+06,1.017
|
||||
CopyOnly/citm_catalog,ns,786244,817481,0.962
|
||||
CopyOnly/twitter,ns,423631,420649,1.007
|
||||
CopyRing/canada,ns,3.86433e+06,2.99657e+06,1.290
|
||||
CopyRing/citm_catalog,ns,1.84434e+06,1.60579e+06,1.149
|
||||
CopyRing/twitter,ns,951510,818035,1.163
|
||||
DestroyOnly/canada,ns,2.22138e+06,1.40157e+06,1.585
|
||||
DestroyOnly/citm_catalog,ns,926244,711471,1.302
|
||||
DestroyOnly/twitter,ns,416055,336082,1.238
|
||||
Diff/canada,ns,3.98055e+07,3.80466e+06,10.462
|
||||
Diff/citm_catalog,ns,7.1859e+06,1.12351e+06,6.396
|
||||
Diff/twitter,ns,5.11261e+06,661062,7.734
|
||||
Dump/canada / -,ns,6.95189e+06,2.33647e+06,2.975
|
||||
Dump/canada / 4,ns,9.09882e+06,3.10291e+06,2.932
|
||||
Dump/citm_catalog / -,ns,1.42117e+06,295678,4.806
|
||||
Dump/citm_catalog / 4,ns,1.98589e+06,422600,4.699
|
||||
Dump/floats / -,ns,6.4332e+07,2.37747e+07,2.706
|
||||
Dump/floats / 4,ns,7.25695e+07,2.46207e+07,2.947
|
||||
Dump/jeopardy / -,ns,2.06771e+08,3.17494e+07,6.513
|
||||
Dump/jeopardy / 4,ns,2.27967e+08,3.53626e+07,6.447
|
||||
Dump/signed_ints / -,ns,2.40551e+07,1.0736e+07,2.241
|
||||
Dump/signed_ints / 4,ns,3.25192e+07,1.1333e+07,2.869
|
||||
Dump/small_signed_ints / -,ns,1.81398e+07,8.12457e+06,2.233
|
||||
Dump/small_signed_ints / 4,ns,2.55296e+07,8.80796e+06,2.898
|
||||
Dump/twitter / -,ns,1.43584e+06,214252,6.702
|
||||
Dump/twitter / 4,ns,1.63183e+06,253042,6.449
|
||||
Dump/unsigned_ints / -,ns,2.39512e+07,8.11916e+06,2.950
|
||||
Dump/unsigned_ints / 4,ns,3.22761e+07,8.58925e+06,3.758
|
||||
Equal/canada,ns,473767,349284,1.356
|
||||
Equal/citm_catalog,ns,279548,263329,1.062
|
||||
Equal/twitter,ns,145555,131450,1.107
|
||||
Flatten/canada,ns,2.94475e+07,1.11184e+07,2.649
|
||||
Flatten/citm_catalog,ns,6.7155e+06,3.07325e+06,2.185
|
||||
Flatten/twitter,ns,3.66077e+06,2.10599e+06,1.738
|
||||
FlattenOrdered/citm_catalog,ns,2.62026e+08,1.42645e+06,183.691
|
||||
FlattenOrdered/twitter,ns,5.1275e+07,890275,57.595
|
||||
FromBinaryBuffer/bjdata / canada,ns,8.81972e+06,4.16727e+06,2.116
|
||||
FromBinaryBuffer/bjdata / twitter,ns,3.32045e+06,976266,3.401
|
||||
FromBinaryBuffer/bjdata_optimized / canada,ns,9.2386e+06,2.47996e+06,3.725
|
||||
FromBinaryBuffer/bjdata_optimized / twitter,ns,3.30526e+06,985625,3.353
|
||||
FromBinaryBuffer/bson / canada,ns,1.00372e+07,4.31554e+06,2.326
|
||||
FromBinaryBuffer/bson / citm_catalog,ns,4.07611e+06,1.60647e+06,2.537
|
||||
FromBinaryBuffer/bson / twitter,ns,3.25635e+06,936933,3.476
|
||||
FromBinaryBuffer/cbor / canada,ns,8.89562e+06,2.11517e+06,4.206
|
||||
FromBinaryBuffer/cbor / citm_catalog,ns,3.94234e+06,1.45242e+06,2.714
|
||||
FromBinaryBuffer/cbor / floats,ns,3.0473e+07,5.47969e+06,5.561
|
||||
FromBinaryBuffer/cbor / jeopardy,ns,3.73185e+08,1.14934e+08,3.247
|
||||
FromBinaryBuffer/cbor / signed_ints,ns,3.66673e+07,9.88892e+06,3.708
|
||||
FromBinaryBuffer/cbor / twitter,ns,3.23196e+06,953415,3.390
|
||||
FromBinaryBuffer/msgpack / canada,ns,8.85983e+06,2.12215e+06,4.175
|
||||
FromBinaryBuffer/msgpack / citm_catalog,ns,3.84901e+06,1.4503e+06,2.654
|
||||
FromBinaryBuffer/msgpack / jeopardy,ns,3.73143e+08,1.11034e+08,3.361
|
||||
FromBinaryBuffer/msgpack / twitter,ns,3.2397e+06,954811,3.393
|
||||
FromBinaryBuffer/ubjson / canada,ns,8.84059e+06,4.20402e+06,2.103
|
||||
FromBinaryBuffer/ubjson / citm_catalog,ns,4.0708e+06,1.78566e+06,2.280
|
||||
FromBinaryBuffer/ubjson / jeopardy,ns,3.79093e+08,1.17024e+08,3.239
|
||||
FromBinaryBuffer/ubjson / twitter,ns,3.29948e+06,981057,3.363
|
||||
FromBinaryBuffer/ubjson_optimized / canada,ns,8.88909e+06,2.42788e+06,3.661
|
||||
FromBinaryBuffer/ubjson_optimized / twitter,ns,3.29784e+06,974810,3.383
|
||||
FromBinaryFile/bjdata / twitter,ns,1.09208e+07,1.94678e+06,5.610
|
||||
FromBinaryFile/bson / twitter,ns,1.07209e+07,1.84971e+06,5.796
|
||||
FromBinaryFile/cbor / canada,ns,1.49218e+07,4.48832e+06,3.325
|
||||
FromBinaryFile/cbor / twitter,ns,1.03718e+07,1.57388e+06,6.590
|
||||
FromBinaryFile/ubjson / canada,ns,1.43414e+07,6.42996e+06,2.230
|
||||
FromBinaryFile/ubjson / twitter,ns,1.09266e+07,1.97275e+06,5.539
|
||||
FromBinaryShape/containers / bjdata,ns,1.46977e+07,7.23447e+06,2.032
|
||||
FromBinaryShape/containers / bson,ns,1.75596e+07,7.88867e+06,2.226
|
||||
FromBinaryShape/containers / cbor,ns,1.46488e+07,4.15792e+06,3.523
|
||||
FromBinaryShape/containers / msgpack,ns,1.45853e+07,3.89266e+06,3.747
|
||||
FromBinaryShape/containers / ubjson,ns,1.49773e+07,7.23987e+06,2.069
|
||||
FromBinaryShape/containers / ubjson_optimized,ns,1.54989e+07,4.55976e+06,3.399
|
||||
FromBinaryShape/nested / bjdata,ns,96825.9,38335.1,2.526
|
||||
FromBinaryShape/nested / bson,ns,101356,42620.2,2.378
|
||||
FromBinaryShape/nested / cbor,ns,94929.8,35845.6,2.648
|
||||
FromBinaryShape/nested / msgpack,ns,92610.2,35078.3,2.640
|
||||
FromBinaryShape/nested / ubjson,ns,96090.6,38285.6,2.510
|
||||
FromBinaryShape/scalars / bjdata,ns,2.52616e+07,1.15856e+07,2.180
|
||||
FromBinaryShape/scalars / cbor,ns,2.62118e+07,5.88743e+06,4.452
|
||||
FromBinaryShape/scalars / msgpack,ns,2.50706e+07,5.65159e+06,4.436
|
||||
FromBinaryShape/scalars / ubjson,ns,2.53402e+07,1.16191e+07,2.181
|
||||
FromCborChunkedString/10000 chunks,ns,91845.9,82875.5,1.108
|
||||
FromMsgpack/canada,ns,1.48853e+07,4.56225e+06,3.263
|
||||
FromMsgpack/citm_catalog,ns,9.3559e+06,2.26246e+06,4.135
|
||||
FromMsgpack/floats,ns,6.12575e+07,2.86709e+07,2.137
|
||||
FromMsgpack/jeopardy,ns,1.16767e+09,1.90153e+08,6.141
|
||||
FromMsgpack/signed_ints,ns,6.38812e+07,3.28867e+07,1.942
|
||||
FromMsgpack/small_signed_ints,ns,6.44688e+07,3.44227e+07,1.873
|
||||
FromMsgpack/twitter,ns,1.02787e+07,1.48541e+06,6.920
|
||||
FromMsgpack/unsigned_ints,ns,5.7784e+07,2.83078e+07,2.041
|
||||
"GetArray<std::array<int, 1000>>",ns,2274.63,654.431,3.476
|
||||
GetArray<std::deque<int>>,ns,8288.3,1175.75,7.049
|
||||
GetArray<std::set<int>>,ns,60017.4,42504.9,1.412
|
||||
GetArray<std::vector<int>>,ns,6785.73,681.915,9.951
|
||||
GetMap/citm_catalog,ns,3.60313e+06,2.48546e+06,1.450
|
||||
GetVectorDouble/floats,ns,6.83612e+06,656162,10.418
|
||||
GetVectorInt/signed_ints,ns,8.22365e+06,3.46495e+06,2.373
|
||||
Iterate/canada,ns,897083,328035,2.735
|
||||
Iterate/citm_catalog,ns,305421,171245,1.784
|
||||
Iterate/twitter,ns,89996.6,61975.8,1.452
|
||||
JsonPointerAt/citm_catalog,ns,1.89898e+06,1.17751e+06,1.613
|
||||
JsonPointerAt/twitter,ns,817946,611519,1.338
|
||||
JsonPointerContains/citm_catalog,ns,2.8177e+06,1.26796e+06,2.222
|
||||
JsonPointerContains/twitter,ns,1.33508e+06,628630,2.124
|
||||
JsonPointerParse/citm_catalog,ns,5.81355e+06,2.24831e+06,2.586
|
||||
JsonPointerParse/twitter,ns,2.47971e+06,1.02159e+06,2.427
|
||||
JsonPointerToString/citm_catalog,ns,6.7858e+06,1.93924e+06,3.499
|
||||
JsonPointerToString/twitter,ns,2.23096e+06,834416,2.674
|
||||
ParseFILE/canada,ns,5.41907e+07,1.46942e+07,3.688
|
||||
ParseFILE/citm_catalog,ns,3.59542e+07,7.58092e+06,4.743
|
||||
ParseFILE/twitter,ns,1.4087e+07,3.44991e+06,4.083
|
||||
ParseFile/canada,ns,1.82792e+07,6.46954e+06,2.825
|
||||
ParseFile/citm_catalog,ns,8.12979e+06,2.52336e+06,3.222
|
||||
ParseFile/floats,ns,1.31229e+08,4.81407e+07,2.726
|
||||
ParseFile/jeopardy,ns,3.38017e+08,1.62098e+08,2.085
|
||||
ParseFile/signed_ints,ns,1.28749e+08,4.62304e+07,2.785
|
||||
ParseFile/small_signed_ints,ns,6.47398e+07,3.34103e+07,1.938
|
||||
ParseFile/twitter,ns,3.43041e+06,1.37495e+06,2.495
|
||||
ParseFile/unsigned_ints,ns,1.24001e+08,4.74365e+07,2.614
|
||||
ParseIndented/canada / 4,ns,3.4977e+07,5.37149e+06,6.512
|
||||
ParseIndented/citm_catalog / 4,ns,7.52423e+06,1.81376e+06,4.148
|
||||
ParseIndented/jeopardy / 4,ns,3.45046e+08,1.33383e+08,2.587
|
||||
ParseIndented/twitter / 4,ns,3.72283e+06,1.12645e+06,3.305
|
||||
ParseStreamValues/ndjson,ns,7.15876e+06,3.76965e+06,1.899
|
||||
ParseStreamValues/numbers,ns,1.92619e+06,383138,5.027
|
||||
ParseString/canada,ns,1.55213e+07,4.62776e+06,3.354
|
||||
ParseString/citm_catalog,ns,7.56417e+06,1.77967e+06,4.250
|
||||
ParseString/floats,ns,1.21779e+08,2.83035e+07,4.303
|
||||
ParseString/jeopardy,ns,3.16817e+08,1.30897e+08,2.420
|
||||
ParseString/signed_ints,ns,1.22931e+08,3.19852e+07,3.843
|
||||
ParseString/small_signed_ints,ns,6.2685e+07,2.49764e+07,2.510
|
||||
ParseString/twitter,ns,3.2961e+06,1.04867e+06,3.143
|
||||
ParseString/unsigned_ints,ns,1.21229e+08,3.29241e+07,3.682
|
||||
ParseStringOrdered/canada,ns,1.5388e+07,4.5275e+06,3.399
|
||||
ParseStringOrdered/citm_catalog,ns,1.15204e+07,1.68115e+06,6.853
|
||||
ParseStringOrdered/jeopardy,ns,3.73533e+08,1.13397e+08,3.294
|
||||
ParseStringOrdered/twitter,ns,4.5979e+06,948606,4.847
|
||||
Patch/canada,ns,1.03684e+07,3.47719e+06,2.982
|
||||
Patch/citm_catalog,ns,2.74522e+06,1.74191e+06,1.576
|
||||
Patch/twitter,ns,1.57928e+06,888657,1.777
|
||||
SaxParse/canada,ns,1.31023e+07,3.26697e+06,4.011
|
||||
SaxParse/citm_catalog,ns,6.54642e+06,966806,6.771
|
||||
SaxParse/twitter,ns,2.53102e+06,483052,5.240
|
||||
ToCbor/canada,ns,1.41339e+06,556912,2.538
|
||||
ToCbor/citm_catalog,ns,1.04743e+06,259178,4.041
|
||||
ToCbor/floats,ns,9.04677e+06,1.90094e+06,4.759
|
||||
ToCbor/jeopardy,ns,7.39339e+07,2.20678e+07,3.350
|
||||
ToCbor/signed_ints,ns,1.15333e+07,2.827e+06,4.080
|
||||
ToCbor/small_signed_ints,ns,1.0394e+07,2.47974e+06,4.192
|
||||
ToCbor/twitter,ns,658566,143397,4.593
|
||||
ToCbor/unsigned_ints,ns,8.17966e+06,2.81588e+06,2.905
|
||||
ToJsonStrings/copy,ns,6.12e+06,5.65303e+06,1.083
|
||||
ToJsonStrings/move,ns,6.13061e+06,3.13303e+06,1.957
|
||||
Unflatten/canada,ns,4.25276e+07,1.10995e+07,3.831
|
||||
Unflatten/citm_catalog,ns,1.01866e+07,3.62185e+06,2.813
|
||||
Unflatten/twitter,ns,4.74536e+06,2.21103e+06,2.146
|
||||
|
@@ -1,354 +0,0 @@
|
||||
index,commit,date,pr,subject,parse_twitter,parse_citm,parse_canada,parse_citm_compact,parse_twitter_ifstream,accept_twitter,dump_twitter,dump_citm,dump_canada,dump4_citm,from_cbor_twitter,to_cbor_twitter,copy_destroy_citm,equal_citm,view_parse_twitter,view_parse_citm,view_parse_canada
|
||||
0,55f93686c0,2025-04-11,,Merge branch 'release/3.12.0',3571.487,8219.609,17049.073,4366.792,3846.006,2394.213,1441.213,1375.446,7510.989,1917.809,3463.281,695.524,1643.327,1956.891,,,
|
||||
1,1705bfe914,2025-04-11,4727,:bookmark: set version to 3.12.0 (#4727),3589.331,8245.422,17079.250,4422.711,3894.787,2397.597,1440.546,1377.745,7514.698,1922.371,3498.997,695.559,1655.240,1967.301,,,
|
||||
2,4cca3b9cb2,2025-04-13,4738,Fix warning and add emscripten CI step (#4738),3559.657,8195.105,17066.291,4373.011,3794.269,2388.900,1419.182,1355.724,7420.703,1912.038,3468.667,664.214,1631.610,1939.475,,,
|
||||
3,96c1b52f1c,2025-04-15,4742,Fix conversion to std::optional (#4742),3573.838,8157.276,16993.208,4383.656,3858.927,2395.092,1438.169,1372.208,7497.776,1925.481,3482.185,667.895,1633.619,1946.687,,,
|
||||
4,88c92e605c,2025-04-16,4744,Fix compilation failure and warnings with NVHPC (#4744),3563.149,8039.911,16922.739,4381.927,3768.560,2385.086,1407.564,1345.578,7370.063,1897.474,3462.010,662.955,1623.286,1925.804,,,
|
||||
5,c67d538274,2025-04-17,4749,Fix C4702 warning and extend MSVC CI job (#4749),3585.422,8251.057,17050.448,4400.542,3896.586,2390.655,1440.391,1371.722,7453.474,1921.277,3478.523,667.911,1636.206,1939.531,,,
|
||||
6,756ca22ec5,2025-04-23,4736,Provide fallback for missing `char8_t` support (#4736),3559.146,8139.703,17085.114,4387.658,3856.745,2392.849,1424.997,1370.599,7477.537,1907.661,3484.427,665.541,1634.156,1957.401,,,
|
||||
7,6b9199382b,2025-04-27,4763,Add missing header (#4763),3541.323,8077.761,17011.636,4359.183,3842.380,2396.686,1421.116,1363.737,7431.375,1902.909,3474.250,664.442,1625.644,1934.732,,,
|
||||
8,3b02afb9d9,2025-04-28,4760,Specialize char_traits for std::byte to fix from_msgpack (fixes #4756) (#4760),3583.070,8198.146,17134.698,4381.743,3899.872,2409.185,1440.233,1380.810,7504.838,1921.781,3500.125,666.078,1657.207,1966.036,,,
|
||||
9,eef76c200e,2025-04-28,4764,Make library work with C++20 modules (#4764),3528.529,8080.458,16936.656,4330.570,3764.287,2363.848,1407.851,1358.079,7356.239,1897.423,3455.287,665.194,1632.255,1937.675,,,
|
||||
10,dff2b4756c,2025-04-29,4765,fix: BJData size calculation overflow (#4765),3553.706,8141.375,17047.511,4360.144,3797.070,2389.756,1417.737,1364.718,7454.313,1921.962,3479.878,666.456,1644.760,1944.696,,,
|
||||
11,9110918cf8,2025-05-04,4748,Fix typos (#4748),3563.682,8176.427,17239.354,4398.055,3891.669,2399.782,1441.669,1387.133,7516.073,1925.323,3483.271,669.348,1647.760,1957.747,,,
|
||||
12,46e7cd3dc2,2025-05-16,4775,Replace deprecated std::is_trivial in C++26 (#4775),3565.242,8195.396,17135.646,4373.479,3851.604,2392.258,1418.425,1370.958,7464.854,1909.844,3485.046,665.606,1643.155,1952.329,,,
|
||||
13,828c891427,2025-05-16,4786,Extend type_name() to invalid type (#4786),3549.573,8103.761,17066.198,4359.911,3804.849,2389.121,1428.584,1366.405,7424.838,1914.434,3452.497,667.452,1632.750,1928.324,,,
|
||||
14,4b17f90f65,2025-05-22,4609,Add `ignore_trailing_commas` option (#4609),3544.662,8132.052,16997.375,4344.592,3825.765,2382.755,1408.435,1367.468,7460.448,1924.522,3434.062,733.089,1631.356,1891.572,,,
|
||||
15,b19f058465,2025-06-01,4802,Encode infinity and NaN as float for MsgPack and CBOR (#4802),3550.020,8126.438,17350.885,4327.596,3825.419,2389.356,1409.422,1376.649,7363.802,1921.226,3441.081,683.190,1624.144,1886.388,,,
|
||||
16,cf16c5ab9f,2025-06-02,4805,Use binary_t::value_type (#4805),3551.735,8143.521,17153.291,4309.477,3829.229,2387.640,1428.550,1385.585,7415.271,1932.347,3425.838,657.735,1631.586,1888.954,,,
|
||||
17,d70e46bc65,2025-06-25,4830,:bug: add missing header to input_adapters.hpp (#4830),3546.448,8157.469,17062.364,4335.300,3805.221,2382.796,1422.863,1382.581,7411.401,1928.676,3433.190,691.842,1632.972,1892.453,,,
|
||||
18,30d27df61c,2025-07-31,4871,Fix CI (#4871),3570.015,8150.859,17070.625,4330.078,3806.505,2400.329,1434.947,1381.065,7425.718,1931.556,3429.632,656.545,1633.515,1892.916,,,
|
||||
19,efcf9efb4f,2025-08-02,4873,Fixes #4854 Explicitly handle nullptr in sax_parse (#4873),3520.381,8050.719,16883.042,4331.820,3861.906,2368.069,1408.435,1375.954,7363.651,1898.466,3432.992,653.988,1634.141,1894.948,,,
|
||||
20,4106af8d92,2025-08-20,4896,":rotating_light: suppress cppcoreguidelines-c-copy-assignment-signature,misc-unconventional-assign-operator (#4896)",3540.599,8175.265,17010.438,4345.182,3866.833,2393.935,1435.100,1389.496,7453.724,1945.791,3433.169,657.446,1638.434,1900.360,,,
|
||||
21,a63795caf1,2025-10-22,4791,:rotating_light: avoid deprecation warning (#4791),3550.057,8174.646,16983.177,4363.521,3888.336,2393.305,1423.434,1376.334,7469.407,1936.013,3447.279,666.706,1645.354,1903.707,,,
|
||||
22,1cc56b2dcd,2025-10-23,4957,Address CWG issue 2521 (#4957),3557.396,8119.651,17072.730,4351.881,3834.739,2386.097,1442.100,1393.245,7474.463,1932.315,3446.883,660.187,1638.983,1896.000,,,
|
||||
23,54be9b04f0,2025-10-23,4960,:page_facing_up: update REUSE (#4960),3554.625,8098.287,17115.219,4324.578,3809.950,2390.791,1424.488,1376.715,7422.828,1913.208,3424.693,659.030,1623.405,1892.756,,,
|
||||
24,29913ca760,2025-10-25,4963,Add char8_t* overload for _json and _json_pointer (#4963),3544.899,8169.203,17007.844,4353.594,3797.630,2392.108,1423.032,1375.216,7349.787,1909.897,3428.771,655.625,1635.273,1891.018,,,
|
||||
25,515d994acb,2026-01-01,5044,:page_facing_up: adjust year (#5044),3524.610,8059.521,16949.416,4313.508,3773.750,2364.742,1410.427,1372.988,7382.438,1915.502,3403.159,643.968,1618.972,1884.213,,,
|
||||
26,8f75700141,2026-01-11,4958,support types convertible to string_view as JSON keys (#4958),3546.757,8142.599,17103.386,4327.739,3825.990,2388.540,1420.515,1379.309,7413.062,1924.540,3433.677,658.266,1628.079,1890.759,,,
|
||||
27,457bc283ff,2026-01-12,5039,fix(cbor): reject overflowing negative integers (#5039),3508.883,8077.291,16930.011,4305.982,3785.698,2378.693,1425.526,1366.111,7407.042,1929.142,3478.909,657.722,1636.304,1944.681,,,
|
||||
28,e3014f162a,2026-01-13,5052,Fix conversion to std::optional (#5052),3547.995,8140.052,17010.031,4321.914,3797.807,2385.856,1430.414,1386.202,7407.260,1930.403,3462.213,657.829,1629.579,1932.066,,,
|
||||
29,5ed07097fa,2026-01-13,5050,Fix -Wtautological-constant-out-of-range-compare in serializer (#5050),3544.136,8180.208,17033.209,4339.591,3799.779,2391.940,1427.870,1387.871,7368.765,1922.321,3454.938,659.367,1630.707,1959.722,,,
|
||||
30,25f48639c7,2026-01-23,5016,Reference tuple from json (#5016),3563.180,8209.037,17030.969,4388.675,3895.086,2392.088,1430.666,1393.853,7528.567,1934.347,3481.351,677.234,1645.418,1957.591,,,
|
||||
31,f8eee1bb79,2026-02-07,5071,Annotate unreachable comment-scanner switch paths to satisfy C26819 (#5071),3508.000,8128.750,16958.959,4315.235,3797.237,2371.963,1425.146,1374.867,7453.381,1930.211,3456.508,658.568,1629.188,1909.736,,,
|
||||
32,fd17b0889e,2026-05-08,5139,Remove nullptr safety check from sax_parse functions (#5139),3544.101,8033.021,16963.292,4334.102,3800.736,2382.583,1419.050,1361.745,7357.073,1907.153,3429.315,657.041,1618.815,1937.829,,,
|
||||
33,62f3b41b30,2026-05-08,5090,fix: treat single-element brace-init as copy/move instead of wrapping in array (#5074) (#5090),3550.323,8168.713,17060.031,4349.417,3794.110,2380.583,1416.822,1361.182,7369.651,1897.717,3466.731,659.297,1631.463,1941.905,,,
|
||||
34,4fad446897,2026-05-10,5162,docs: add IDs to @requirement tags to fix Doxygen autolinking (#5162),3545.440,8031.891,17069.448,4324.698,3802.862,2383.513,1422.768,1384.602,7325.776,1917.606,3469.787,659.011,1631.296,1940.370,,,
|
||||
35,a0a4e7cc0b,2026-05-13,5152,Add front methods to json_pointers (implements #4889) (#5152),3582.898,8215.010,17034.448,4345.515,3891.513,2396.572,1432.733,1395.714,7554.119,1934.008,3484.859,659.298,1642.314,1957.356,,,
|
||||
36,93e49decbd,2026-05-14,5167,Fix incomplete-type error in set_parents with ordered_json (#5167),3555.224,8147.771,17017.073,4320.846,3831.318,2386.750,1435.840,1385.578,7436.864,1927.483,3466.508,658.409,1632.724,1939.528,,,
|
||||
37,7192763f15,2026-05-14,5163,Fix compile error when using nlohmann ordered_map with WITH_DEFAULT macros (#5163),3520.675,8039.145,16892.291,4303.448,3769.198,2363.337,1410.030,1364.679,7380.797,1913.285,3437.278,660.130,1630.738,1943.235,,,
|
||||
38,5a05627b1f,2026-05-14,5169,:rotating_light: fix warning (#5169),3600.555,8160.854,16979.031,4324.070,3887.823,2389.157,1430.983,1387.106,7509.984,1912.601,3473.713,663.279,1652.982,1958.774,,,
|
||||
39,bb5404bb86,2026-05-15,5164,Fix GCC C++20 modules compilation #5103 (#5164),3543.823,8120.266,17015.395,4349.300,3794.880,2364.178,1414.408,1374.548,7484.218,1920.495,3444.266,699.326,1626.241,1954.688,,,
|
||||
40,b1bb9fce0c,2026-05-15,3929,Fix for printing long doubles bug in dump_float (#3929),3549.378,8089.891,16934.927,4313.310,3824.802,2386.958,1412.164,1385.425,7417.869,1930.513,3461.151,651.557,1618.735,1944.450,,,
|
||||
41,cba5dc0ed8,2026-05-16,4563,New macros for the named JSON convertor generation (#4563),3544.657,8168.182,16990.886,4327.688,3806.963,2370.975,1421.629,1390.206,7454.151,1919.284,3452.456,677.413,1623.622,1941.921,,,
|
||||
42,47202c804a,2026-05-18,5171,Add missing overload to ordered_map::find (#5171),3527.542,8168.312,17141.989,4409.456,3887.378,2397.007,1428.765,1387.033,7495.604,1935.710,3485.088,660.155,1648.977,1951.430,,,
|
||||
43,58cfecf7f7,2026-05-18,5151,Serialize enum (#5151),3521.302,8100.104,16805.489,4288.463,3763.971,2381.494,1408.713,1383.059,7328.261,1915.202,3440.372,648.726,1617.661,1922.608,,,
|
||||
44,584e6b1cfb,2026-05-22,5187,Fix: update() parent pointers not updated after recursive merge with JSON_DIAGNOSTICS (#5187),3550.639,8083.463,17055.198,4326.833,3804.257,2381.519,1432.039,1381.986,7377.844,1915.159,3460.750,656.873,1631.527,1940.953,,,
|
||||
45,02dfbea39d,2026-06-17,5209,added explicit instantiations of 'has_from_json' and 'has_to_json' for std_fs::path (#5209),3552.209,8215.474,17167.760,4338.404,3845.144,2398.026,1425.012,1387.629,7458.614,1931.388,3475.343,658.183,1644.329,1958.324,,,
|
||||
46,fc1df0b7db,2026-06-23,5172,:recycle: remove unnecessary if (#5172),3562.088,8175.531,17044.042,4336.583,3863.651,2404.695,1425.872,1389.434,7523.855,1914.128,3481.000,653.259,1639.515,1957.649,,,
|
||||
47,c5b2b26fdc,2026-06-29,5217,:memo: fix docs (#5217),3526.825,8052.307,17000.011,4343.963,3793.412,2388.194,1416.706,1374.177,7361.646,1904.008,3463.919,658.322,1627.765,1921.887,,,
|
||||
48,b7566c6293,2026-06-30,5161,Harden JSON_HAS_RANGES detection for incomplete C++20 ranges implementations (#5161),3538.995,8071.787,17120.751,4318.797,3772.445,2384.008,1421.440,1385.239,7419.292,1898.929,3431.466,647.948,1602.258,1928.644,,,
|
||||
49,adf78d3a76,2026-06-30,5215,Minor: unique_ptr template resolution workaround for MSVC (#5215),3550.380,8138.026,17036.802,4366.062,3842.430,2389.536,1426.658,1385.609,7428.787,1915.233,3467.188,658.332,1636.158,1942.556,,,
|
||||
50,272411c5e6,2026-06-30,5218,Overwork project infrastructure (#5218),3547.487,8087.250,16962.198,4341.969,3793.831,2387.509,1420.888,1381.072,7450.078,1930.003,3466.193,659.676,1631.329,1943.043,,,
|
||||
51,730b57775d,2026-07-01,5222,:bug: avoid assertion in patch (#5222),3539.912,8169.771,17027.229,4345.151,3790.753,2376.552,1421.263,1386.717,7399.985,1923.237,3455.722,653.609,1630.914,1934.028,,,
|
||||
52,ca49ab6123,2026-07-02,5223,Extend value to arrays when using JSON pointers (#5223),3550.341,8113.787,16951.313,4346.805,3793.097,2391.224,1409.695,1380.075,7374.073,1926.401,3458.438,659.382,1629.387,1941.306,,,
|
||||
53,8d7e0046f4,2026-07-02,5224,Add std::format and fmt support (#5224),3546.935,8170.406,16968.927,4346.906,3814.956,2387.612,1424.861,1386.542,7350.765,1900.376,3461.177,662.476,1633.858,1930.434,,,
|
||||
54,31dd15b258,2026-07-02,5221,Fix ambiguous static_cast (#5221),3551.945,8213.000,17131.271,4373.620,3845.763,2393.074,1438.633,1385.769,7471.146,1927.804,3486.568,662.015,1631.810,1958.901,,,
|
||||
55,eed1587000,2026-07-05,5234,Reconstruct lexer diagnostics lazily for seekable input (#120) (#5234),3145.909,5311.094,15381.843,4292.961,3851.260,1966.833,1422.598,1365.461,7443.276,1920.467,3467.060,702.832,1637.587,1905.758,,,
|
||||
56,83c87cb9e0,2026-07-05,5233,Read binary strings/blobs in bulk chunks with a memcpy fast path (#5233),3141.867,5259.485,15454.959,4326.664,3797.198,1987.623,1406.492,1372.765,7424.729,1899.726,2363.895,667.502,1630.097,1888.392,,,
|
||||
57,acf076a677,2026-07-06,5238,Fix ADL leak of nlohmann::detail through basic_json's default base class (#5238),3152.153,5277.073,15291.407,4338.828,3839.331,1995.524,1429.960,1365.917,7456.776,1907.928,2398.016,670.257,1627.590,1897.997,,,
|
||||
58,c05c5e229b,2026-07-07,5241,Add missing copyright notices to SBOM (#5241),3147.485,5268.865,15319.584,4321.823,3796.972,1981.167,1432.689,1371.264,7465.416,1918.083,2388.154,667.119,1630.745,1891.583,,,
|
||||
59,366f3d26e5,2026-07-08,5235,Replace snprintf with a branch-free writer for \uXXXX escapes (#5235),3127.641,5272.302,15425.239,4340.459,3850.357,1997.957,1459.603,1356.461,7509.703,1899.916,2366.966,668.383,1624.981,1889.145,,,
|
||||
60,f8e99e856c,2026-07-09,5248,Fix nvcc CUDA 12.0/12.1 C++20 ranges parse error (#3907) (#5248),3132.099,5226.375,15164.510,4301.901,3769.651,1967.647,1456.759,1365.810,7530.724,1908.635,2381.610,683.815,1616.699,1879.795,,,
|
||||
61,855f511db4,2026-07-09,5250,Fix stale Clang -Weverything suppression comments; drop -Wno-missing-noreturn (#5250),3126.792,5208.338,15352.520,4293.596,3800.544,1969.497,1458.601,1329.851,7372.849,1876.404,2368.894,662.173,1603.881,1874.673,,,
|
||||
62,d0a43141ea,2026-07-09,5253,Fix #3868: Remove operator!= to enable P2468R2 rewritten candidate synthesis (#5253),3165.182,5270.458,15479.031,4302.729,3845.646,1989.231,1474.135,1343.312,7443.282,1887.909,2392.523,670.395,1634.871,1894.474,,,
|
||||
63,b630f5e9c7,2026-07-10,5260,Fix container input_adapter SFINAE for lvalue-only ADL begin/end (#5260),3128.117,5263.807,15375.677,4330.544,3819.953,1982.196,1454.088,1339.062,7364.683,1877.699,2361.482,666.486,1616.514,1920.626,,,
|
||||
64,c60217e801,2026-07-11,5205,fix: support constructing json from C++20 range views (#4916) (#5205),3117.539,5206.552,15308.166,4320.513,3798.713,1983.458,1447.072,1350.950,7357.213,1875.632,2340.731,662.905,1633.357,1934.261,,,
|
||||
65,fe2bcc080f,2026-07-11,5266,Custom BinaryType direct assignment (#5266),3174.528,5284.562,15383.645,4328.120,3895.086,1996.913,1478.427,1355.569,7512.115,1899.236,2398.490,672.118,1642.910,1967.660,,,
|
||||
66,ca76c37650,2026-07-11,5265,Add iterator+sentinel tests and docs for binary deserializers (#5265),3134.265,5218.021,15352.521,4306.284,3791.612,1967.824,1451.953,1358.685,7508.828,1891.697,2377.848,665.474,1631.495,1934.907,,,
|
||||
67,c197feff81,2026-07-12,5268,Extend memcpy fast path to sized sentinels (e.g. std::counted_iterator) (#5268),3116.271,5207.146,15415.771,4272.443,3815.851,1984.966,1451.103,1341.093,7328.037,1865.385,2383.169,664.494,1617.967,1915.428,,,
|
||||
68,1c5a953de5,2026-07-19,5276,reject unpaired UTF-16 surrogates in wide-string input (#5276),3155.360,5299.631,15419.812,4302.089,3853.104,1987.259,1468.653,1349.665,7549.432,1911.365,2457.555,680.311,1653.282,1955.673,,,
|
||||
69,3565f40229,2026-07-20,5284,reject negative UBJSON/BJData string length (#5284),3170.456,5301.698,15404.416,4351.226,3893.594,1997.034,1470.907,1358.245,7491.480,1909.601,2401.384,671.260,1639.865,1963.899,,,
|
||||
70,9a3ebb9456,2026-07-23,5287,validate BSON document size against the bytes read (#5287),3157.646,5264.062,15305.271,4338.672,3839.643,1987.196,1461.356,1351.630,7444.791,1890.626,2398.503,665.262,1655.798,1930.268,,,
|
||||
71,8ec98e2c9e,2026-07-27,5313,adding cleanups to bson writer (#5313),3150.448,5268.948,15445.927,4308.612,3805.005,1989.643,1466.348,1349.591,7326.453,1895.842,2393.278,708.164,1644.025,1946.652,,,
|
||||
72,2e23687092,2026-07-28,5314,to_bson() silently emits corrupt documents when a length exceeds INT32_MAX (#5314),3146.534,5254.547,15445.250,4304.008,3798.620,1986.260,1459.735,1345.534,7517.651,1903.996,2395.155,674.344,1644.565,1952.682,,,
|
||||
73,868506dcc0,2026-07-30,5335,Fix CBOR half-float assertion bounds (#5335),3167.086,5267.068,15397.979,4351.011,3883.135,2003.345,1468.939,1360.483,7455.230,1909.055,2406.305,679.942,1643.646,1945.639,,,
|
||||
74,dd24e2dffd,2026-07-30,5332,check all BSON reads and add an EOF check for booleans (#5332),3138.315,5284.833,15399.166,4310.513,3847.630,1980.682,1464.104,1344.108,7445.146,1901.512,2400.532,670.850,1635.196,1900.946,,,
|
||||
75,fd72ecfc8c,2026-07-31,5301,validate ndarray element types in write_bjdata_ndarray (#5301),3164.662,5262.141,15399.010,4287.271,3849.318,1988.186,1460.688,1353.767,7458.380,1893.669,2398.485,668.466,1644.018,1921.615,,,
|
||||
76,bc48951128,2026-07-31,5323,Fix UBJSON high-precision floating-point overflow handling (#5323),3155.628,5289.864,15474.375,4324.253,3888.966,2015.068,1477.846,1354.622,7480.730,1905.566,2415.428,668.997,1641.776,1911.819,,,
|
||||
77,d94cbd99dc,2026-07-31,5274,reject CBOR array/map length equal to the indefinite-length marker (#5274),3144.041,5272.193,15466.980,4338.735,3848.849,1999.231,1459.129,1358.119,7507.307,1901.807,2394.972,667.016,1635.960,1899.878,,,
|
||||
78,2222d386c9,2026-07-31,5339,fix: check CBOR tagged subtype reads (#5339),3095.768,5137.792,15064.146,4258.977,3755.229,1965.900,1454.890,1338.066,7399.068,1883.624,2358.193,660.190,1618.172,1939.713,,,
|
||||
79,585929bff9,2026-08-03,5289,Fix Clang deprecation warning for json_pointer operator== with ordered_json (#5289),3142.341,5259.360,15258.271,4275.479,3807.672,1969.704,1453.688,1337.633,7451.037,1879.447,2364.966,661.560,1635.617,1945.709,,,
|
||||
80,5f121d8c50,2026-08-03,5336,avoid sign extension in char_traits<signed char>::to_int_type (#5336),3145.000,5264.880,15441.521,4269.632,3796.781,1983.497,1440.810,1325.232,7427.750,1880.047,2361.899,663.772,1621.595,1912.378,,,
|
||||
81,68f0722a19,2026-08-03,5342,remove discarded array from parent object in end_array (#5342),3161.273,5269.907,15312.469,4335.433,3840.510,1995.965,1465.745,1355.934,7474.901,1895.483,2401.197,657.397,1634.791,1901.902,,,
|
||||
82,dca9d49a33,2026-08-05,5348,reject out-of-range code points in UTF-32 wide-string input (#5348),3119.753,5210.979,15209.260,4273.984,3799.034,1995.297,1459.456,1342.982,7431.646,1891.478,2370.364,653.618,1633.585,1882.753,,,
|
||||
83,9a091d2b82,2026-08-05,5362,Do not write BJData ndarrays whose size overflows std::size_t (#5362),3137.381,5257.312,15286.084,4308.500,3805.325,1995.140,1468.138,1354.729,7510.088,1893.036,2384.577,659.394,1628.260,1890.245,,,
|
||||
84,d5647e6a3b,2026-08-05,5355,Resolve the TODO(niels) in get_ubjson_string (#5355),3121.278,5249.927,15246.011,4292.737,3800.490,1967.087,1443.762,1333.226,7368.953,1862.131,2347.852,644.647,1623.909,1889.958,,,
|
||||
85,bacdabd176,2026-08-05,5361,Fix start_pos() for strings containing escape sequences (#5361),3114.653,5251.619,15253.907,4331.818,3786.156,1960.676,1442.388,1330.247,7354.724,1863.306,2351.588,650.781,1623.543,1886.671,,,
|
||||
86,1c136a66c4,2026-08-06,5363,Move the CBOR doc block to the function it describes (#5363),3124.274,5209.615,15411.897,4293.320,3812.156,1982.854,1457.653,1345.680,7422.343,1884.848,2387.050,656.076,1627.620,1878.737,,,
|
||||
87,6285225fd0,2026-08-12,5211,Fix integer comparison bug (#5211),3159.557,5291.323,15395.395,4329.836,3867.200,1989.476,1456.052,1359.795,7526.860,1879.642,2396.137,659.077,1638.176,1900.416,,,
|
||||
88,b5378e8deb,2026-08-19,5331,Fix CBOR tag handlers not recognizing tags 0-5 and 21-23 (#5331),3172.476,5239.812,15479.917,4295.539,3871.289,2003.439,1473.447,1343.742,7516.875,1888.412,2400.572,645.588,1641.621,1886.531,,,
|
||||
89,2f025f401e,2026-08-25,5380,Throw other_error.502 when UBJSON use_type is set without use_size (#5380),3155.873,5190.312,15144.406,4286.388,3793.805,1968.199,1442.240,1340.929,7373.610,1860.543,2370.570,648.906,1631.207,1893.750,,,
|
||||
90,35705d79d8,2026-08-28,5414,Fix update(merge_objects=true) throwing on primitive-to-object merge (#5414),3169.029,5252.578,15387.292,4340.690,3893.646,1979.616,1472.286,1361.543,7491.302,1903.909,2401.404,659.396,1641.697,1912.409,,,
|
||||
91,137a40b9aa,2026-09-05,5459,Compare integers with floats exactly instead of widening the integer (#5459),3134.229,5259.349,15404.541,4300.146,3846.646,1992.155,1467.919,1351.774,7467.146,1887.255,2391.467,660.347,1631.735,1891.751,,,
|
||||
92,3c875683a5,2026-09-05,5461,Make diff() linear when an array shrinks (#5461),3141.068,5259.000,15271.166,4319.659,3797.088,1983.450,1455.354,1354.676,7444.860,1891.687,2389.333,657.163,1632.998,1887.016,,,
|
||||
93,09b6b6b5ba,2026-09-05,5455,Fix to_bjdata() emitting unparsable output when _ArraySize_ is not an array (#5455),3161.542,5253.047,15311.718,4291.388,3834.264,1992.744,1472.685,1357.680,7409.479,1889.287,2389.501,698.680,1628.237,1888.705,,,
|
||||
94,faa35cc647,2026-09-09,5484,Skip integer conversion in accept()/SAX validation when the value is unused (#5484),3103.654,5222.453,15458.573,4215.765,3804.320,1935.161,1468.660,1353.499,7452.052,1883.191,2383.524,654.441,1631.700,1885.664,,,
|
||||
95,6d86cc0f6b,2026-09-09,5490,Speed up whitespace skipping in the lexer (#5490),3181.328,5276.318,15307.312,4262.771,3877.401,1977.062,1465.196,1356.119,7594.177,1906.814,2388.615,684.926,1636.950,1893.526,,,
|
||||
96,c05347dd54,2026-09-09,5475,Undefine the four JSON_HEDLEY_* macros that leak after including json.hpp (#5475),3147.932,5156.625,15347.990,4217.505,3871.812,1982.807,1458.787,1354.934,7639.328,1879.823,2370.342,674.625,1637.257,1903.903,,,
|
||||
97,d6660cf718,2026-09-09,5485,Route hand-rolled diagnostic pragmas through Hedley (#5485),3116.151,5215.531,15257.499,4189.979,3835.023,1974.111,1459.363,1342.996,7553.802,1887.698,2379.999,669.934,1635.350,1877.492,,,
|
||||
98,c9477ccf91,2026-09-09,5496,Throw when JSON Patch remove's target path resolves through a primitive or null parent (#5496),3138.841,5258.401,15315.417,4201.008,3874.682,1967.630,1446.393,1335.060,7542.708,1870.111,2390.141,668.484,1634.138,1886.981,,,
|
||||
99,8c38e270b5,2026-09-09,5497,Reject JSON Patch move when from is a proper prefix of path (#5497),3183.820,5280.000,15346.969,4222.164,3839.596,1970.753,1470.428,1351.838,7515.344,1895.809,2389.731,673.696,1633.247,1889.546,,,
|
||||
100,a316738cfa,2026-09-09,5471,Add JSON_HEDLEY_WARN_UNUSED_RESULT to the current accept() overloads (#5471),3175.891,5281.302,15397.062,4240.576,3934.333,1981.765,1475.890,1353.387,7625.104,1896.181,2401.097,669.729,1646.133,1895.638,,,
|
||||
101,c9f1d2d646,2026-09-09,5477,Broaden JSON_HEDLEY_WARN_UNUSED_RESULT coverage to pure query functions (#5477),3171.706,5286.880,15430.844,4264.242,3880.943,1979.990,1472.289,1357.283,7569.854,1904.026,2407.487,671.673,1641.521,1889.053,,,
|
||||
102,8e26b9d4b3,2026-09-09,5495,Make contains(json_pointer) return false instead of throwing on unrepresentable array-index tokens (#5495),3163.789,5240.755,15337.698,4226.154,3880.956,1971.912,1475.322,1357.125,7632.281,1904.060,2401.190,678.863,1638.371,1903.385,,,
|
||||
103,b17c272f46,2026-09-09,5472,Reserve capacity in from_json() object conversion when the target container supports it (#5472),3152.899,5257.645,15401.000,4210.846,3885.123,1989.159,1476.637,1359.851,7639.396,1898.981,2408.243,670.075,1633.528,1894.086,,,
|
||||
104,3e2de32226,2026-09-10,5516,Remove unused iomanip include (#5516),3141.349,5253.657,15364.074,4203.969,3847.620,1968.422,1455.035,1352.754,7582.494,1882.051,2371.814,663.504,1630.172,1870.223,,,
|
||||
105,d69fb8654d,2026-09-10,5501,Return the parsed value by move from from_cbor() and friends (#5501),3133.485,5231.662,15309.926,4183.200,3835.662,1971.125,1462.447,1349.563,7479.136,1904.202,1595.991,661.519,1630.278,1883.994,,,
|
||||
106,4a93aa4e2f,2026-09-10,5283,"Speed up parsing of contiguous input (numbers, strings, UTF-8) (#5283)",1963.879,4221.308,11609.531,3278.497,3857.880,927.779,1483.726,1357.793,7483.343,1906.916,1481.419,676.438,1643.746,1895.551,,,
|
||||
107,bfb07786cd,2026-09-10,5473,Fix to_bjdata() silently truncating out-of-range _ArrayData_ elements (#5473),1941.894,4204.971,11726.688,3264.055,3808.784,923.797,1453.071,1351.760,7458.125,1891.470,1473.508,662.164,1633.043,1888.548,,,
|
||||
108,ff80ed3295,2026-09-11,5285,"Speed up dump(), and keep it from overflowing the stack (#5285)",1939.289,4175.541,11781.291,3233.302,3816.101,914.071,441.200,540.473,6895.041,852.214,1478.197,656.635,1632.675,1885.303,,,
|
||||
109,da42a627dc,2026-09-11,5449,Stop dump() from heap-allocating its output adapter per call (#5449),1937.658,4200.966,11639.198,3235.493,3827.695,909.901,448.948,537.008,6909.036,839.027,1479.968,659.210,1643.621,1878.065,,,
|
||||
110,1dc1d09fc6,2026-09-11,5457,Do not search a container for the value the callback rejected (#5457),1937.459,4140.078,11576.803,3271.838,3845.193,924.316,450.148,539.031,6848.776,844.624,1470.333,671.563,1645.624,1900.347,,,
|
||||
111,fae364db24,2026-09-11,5458,Move the scanned string into the value instead of copying it (#5458),1986.146,4110.787,11757.157,3150.932,3830.550,918.517,442.629,539.606,6913.104,843.920,1417.037,655.259,1628.224,1892.991,,,
|
||||
112,dd50f0eb16,2026-09-11,5502,Stop CBOR indefinite-length strings from recursing per chunk (#5502),1987.853,4033.182,11613.834,3116.378,3841.164,915.943,442.366,539.480,6864.130,836.458,1431.035,656.146,1599.574,1885.858,,,
|
||||
113,4bb2de8cc5,2026-09-11,5503,Reject a nested BJData ndarray dimension vector where it is read (#5503),1981.298,4086.276,11569.240,3141.539,3829.870,923.087,444.038,539.863,6800.724,835.434,1429.637,655.448,1628.999,1879.300,,,
|
||||
114,44f8ec30e9,2026-09-11,5504,Bound UBJSON optimized arrays of a valueless type (#5504),2005.265,4092.265,11730.198,3130.635,3863.992,925.033,448.222,542.323,6893.078,849.901,1437.855,662.171,1638.306,1896.324,,,
|
||||
115,0dd8ca9023,2026-09-11,5505,Read MessagePack containers without recursing per nesting level (#5505),2019.983,4105.305,11862.979,3142.581,3891.601,927.092,447.942,543.936,6939.963,845.634,1442.889,656.578,1637.512,1897.815,,,
|
||||
116,91ab3e81f5,2026-09-11,5506,Read CBOR containers and tags without recursing per nesting level (#5506),1986.334,4039.961,11554.094,3118.761,3783.101,912.504,440.410,534.894,6831.943,834.661,1439.061,655.287,1615.619,1869.912,,,
|
||||
117,a14619b354,2026-09-11,5507,Read UBJSON and BJData containers without recursing per nesting level (#5507),2011.959,4095.868,11782.688,3135.264,3873.604,926.014,447.638,541.304,6905.838,846.051,1468.512,664.161,1629.083,1898.772,,,
|
||||
118,0452641c18,2026-09-11,5508,Read BSON documents without recursing per nesting level (#5508),1974.160,4043.887,11662.938,3095.011,3832.744,916.007,439.914,534.149,6904.453,835.615,1450.792,648.298,1616.917,1874.133,,,
|
||||
119,aa391dc0a5,2026-09-11,5520,Fix two develop CI regressions: dump() nodiscard warning and binary-reader const-correctness (#5520),2003.010,4068.010,11771.364,3137.266,3825.247,924.668,442.416,539.478,6847.083,841.996,1460.659,649.378,1633.738,1885.897,,,
|
||||
120,a50c2537eb,2026-09-12,5476,Reserve capped array capacity in json_sax_dom_parser::start_array() for definite-length binary arrays (#5476),1986.488,4063.883,11588.333,3077.995,3827.479,908.419,440.959,539.114,6806.177,833.555,1452.851,662.422,1627.995,1915.388,,,
|
||||
121,c0b2878a44,2026-09-13,5493,Swap diagnostic positions in basic_json::swap() (#5493),2010.881,4081.057,11734.730,3130.919,3882.258,925.490,450.092,542.953,6925.188,848.486,1480.051,698.636,1643.508,1933.941,,,
|
||||
122,1da2f68992,2026-09-14,5522,Only reserve array capacity if the array type supports it (#5522),1972.122,4048.622,11775.062,3107.938,3803.528,909.385,441.204,535.885,6793.927,842.843,1446.330,658.787,1619.239,1899.164,,,
|
||||
123,6487678bc5,2026-09-15,5464,Fix swap(array_t&)/swap(object_t&) to update parent pointers under JSON_DIAGNOSTICS (#5464),2023.028,4116.169,11737.438,3165.172,3893.266,924.912,448.959,541.529,6970.438,852.039,1483.231,689.631,1635.240,1937.356,,,
|
||||
124,c72f37a40d,2026-09-15,5443,Support custom object/array types and improve template parameter handling (#5443),2001.617,4076.547,11666.583,3109.756,3918.206,923.197,450.592,542.266,6901.703,846.558,1468.284,660.116,1641.586,1905.840,,,
|
||||
125,502e9d66f6,2026-09-16,5479,Fix to_bjdata() emitting the Draft-3-only 'B' marker in default Draft-2 mode (#5479),1970.935,4018.060,11445.500,3079.409,3809.050,910.459,444.217,539.291,6851.407,833.755,1444.697,698.040,1626.601,1889.024,,,
|
||||
126,c41152e620,2026-09-16,5494,Fall back to plain-object encoding when to_bjdata()'s _ArrayType_ annotation is not a string (#5494),1979.481,4054.688,11734.292,3085.542,3819.351,916.992,445.126,539.870,6853.005,833.190,1457.166,665.391,1629.586,1888.734,,,
|
||||
127,e564136c22,2026-09-22,5465,Make diff() account for member order in ordered_json objects (#5465),1970.519,4063.744,11605.198,3087.497,3848.867,915.695,447.051,539.711,6835.172,841.402,1452.004,664.560,1640.751,1890.473,,,
|
||||
128,e485441123,2026-09-22,5466,Restore a duplicate key's prior value when the callback rejects its new value (#5466),2012.920,4099.265,11796.895,3156.818,3913.812,931.464,451.403,541.419,6981.041,846.536,1469.521,704.138,1633.327,1905.709,,,
|
||||
129,a2b19d6158,2026-09-22,5467,Honor allow_exceptions=false for excessive array/object size (out_of_range.408) (#5467),1996.478,4084.422,11734.208,3129.099,3850.854,923.499,446.555,539.379,6949.427,842.029,1453.166,694.200,1631.133,1888.865,,,
|
||||
130,d2c1a6a272,2026-09-22,5468,"Reject array insert(pos, first, last) iterators not pointing into an array (#5468)",1983.767,4066.651,11618.667,3128.505,3848.427,914.900,447.603,541.973,6915.265,844.307,1458.762,677.699,1638.789,1892.443,,,
|
||||
131,0b20b7e622,2026-09-22,5469,Reject MessagePack/BSON binary subtypes that don't fit their wire format (#5469),2010.548,4097.476,11681.218,3121.010,3866.146,925.619,448.533,540.786,6957.000,843.349,1463.518,658.302,1630.857,1902.522,,,
|
||||
132,1054b2097e,2026-09-23,5286,Speed up binary writing: value-type output sink + byte-swap number encoding (#5286),1989.739,4101.393,12034.438,3157.240,3853.987,910.115,449.084,555.970,6884.386,864.526,1471.905,656.635,1661.806,1926.233,,,
|
||||
133,ed513715a8,2026-09-24,5534,Document that a NUL byte in the input is treated as end of input (#5534),2016.236,4104.763,11906.323,3141.138,3936.240,916.611,455.397,562.053,6987.917,871.110,1475.622,657.877,1676.934,1936.557,,,
|
||||
134,56b3ee566c,2026-09-24,5389,Fix stack overflow when copying a deeply nested value (#5387) (#5389),1998.356,4051.206,11660.865,3101.107,3834.672,910.072,452.943,544.464,6908.974,849.212,1460.691,638.644,1650.749,1914.423,,,
|
||||
135,918da64657,2026-09-24,5542,Keep BJData ndarray annotations that would not survive a round trip as objects (#5542),2003.009,4042.969,11517.375,3095.122,3815.360,908.444,448.415,539.423,6911.041,840.044,1449.543,671.530,1651.709,1908.408,,,
|
||||
136,8699de3064,2026-09-24,5555,Stop allocating the BJData excluded-marker list per container (#5555),2001.718,4071.333,11686.427,3122.065,3796.757,900.895,447.123,539.918,6860.765,844.752,1444.435,646.608,1644.943,1879.295,,,
|
||||
137,2e91641de2,2026-09-24,5544,"Test JSON_BRACE_INIT_COPY_SEMANTICS for real, and fix one-element tuples under it (#5544)",2004.785,4083.914,11662.270,3119.602,3917.914,922.465,454.869,547.631,6987.234,853.010,1469.612,649.946,1672.246,1913.098,,,
|
||||
138,7c90ec2323,2026-09-24,5546,Hash deeply nested values without recursing per nesting level (#5546),1952.912,4071.159,11594.927,3117.497,3793.052,900.729,444.245,539.787,6854.406,841.264,1457.530,643.139,1638.578,1890.482,,,
|
||||
139,4daca40d7b,2026-09-24,5547,Merge deeply nested objects without recursing per nesting level (#5547),2008.226,4104.399,11619.542,3148.604,3918.175,921.207,457.191,547.553,6942.265,855.352,1464.974,651.924,1665.232,1915.869,,,
|
||||
140,01b53c8c15,2026-09-25,5552,Keep JSON_DIAGNOSTICS parent pointers of ordered_json members after erase() and update() (#5552),1979.354,4061.378,11603.480,3098.586,3875.258,919.125,455.911,546.269,6940.026,849.511,1461.751,648.841,1660.978,1917.254,,,
|
||||
141,abbe52d6de,2026-09-25,5344,Add JSON_PRECISE_STREAM_POSITION to leave the character that terminates a number in the stream (#5344),2001.170,4081.617,11653.531,3131.331,3876.208,915.153,453.436,546.720,6971.864,848.900,1463.182,647.946,1662.943,1906.246,,,
|
||||
142,02dd3e67f2,2026-09-25,5390,Fix stack overflow and exponential runtime when comparing nested values (#5390),1987.861,4074.039,11596.000,3161.284,3901.497,919.541,447.553,543.948,6910.162,845.668,1455.759,664.224,1652.074,1930.575,,,
|
||||
143,465407f3ce,2026-09-25,2818,Improve error message for const fields (#2818),1975.274,4118.565,11863.448,3130.541,3880.764,910.767,452.904,545.363,6906.890,843.118,1459.728,645.770,1654.265,1934.900,,,
|
||||
144,632a5812a8,2026-09-25,5272,Support zero-member types in NLOHMANN_DEFINE_TYPE_* macros (#4041) (#5272),1963.323,4021.526,11747.959,3102.006,3784.896,904.545,444.355,543.748,6840.604,841.416,1438.306,639.223,1649.816,1930.274,,,
|
||||
145,d19f7f5dce,2026-09-25,5185,Fix BSON conformance issue (#5185),1958.606,4048.536,11541.011,3086.805,3817.875,900.452,446.001,544.071,6824.323,837.078,1971.245,641.271,1651.209,1934.647,,,
|
||||
146,c60a0bc336,2026-09-25,5573,Allocate the deep copy's key scratch space with the provided allocator (#5573),1965.216,4021.459,11630.855,3074.078,3807.258,902.782,444.394,542.562,6919.969,840.942,1975.668,645.827,1637.429,1918.607,,,
|
||||
147,1e44262091,2026-09-25,5560,Make JSON_STRICT_NUL_HANDLING part of the ABI tag (#5560),1961.862,4069.617,11594.083,3117.500,3817.758,909.186,448.820,544.420,6845.802,844.016,1977.909,645.864,1651.269,1937.217,,,
|
||||
148,95e9a5931c,2026-09-25,5553,"Write BSON in linear time, without recursing per nesting level (#5553)",1965.832,4033.394,11589.364,3120.422,3792.091,905.110,446.984,543.328,6794.244,844.943,1991.659,640.188,1647.675,1928.562,,,
|
||||
149,fe4a544c7e,2026-09-27,5515,handled when size exceed uint32 (#5515),1998.244,4047.208,11755.209,3091.776,3815.000,908.733,447.990,546.295,6903.084,850.946,1993.351,645.487,1654.343,1933.385,,,
|
||||
150,4fa95d9810,2026-09-27,5583,Remove unreachable branches from the binary writer (#5583),1983.323,4038.331,11666.480,3092.841,3844.935,910.149,449.697,541.110,6840.583,830.604,1979.750,653.542,1650.670,1928.883,,,
|
||||
151,6178982b8d,2026-09-27,5582,Compare unordered objects by key below the nesting bound (#5582),1971.706,4073.498,11600.646,3132.700,3830.323,910.231,448.982,538.812,6836.770,846.149,2007.607,657.180,1653.089,1934.675,,,
|
||||
152,f7972970a4,2026-09-27,5584,Throw instead of writing MessagePack lengths beyond UINT32_MAX (#5584),1969.417,4013.021,11602.447,3083.552,3842.495,904.223,447.444,542.170,6862.735,839.628,2000.766,655.034,1653.006,1939.922,,,
|
||||
153,6bd106893a,2026-09-27,5559,Fix CBOR tag handling in cbor_tag_handler_t::store for non-binary items (#5559),1969.250,4034.693,11691.500,3119.171,3827.860,916.053,455.026,542.577,6886.360,839.718,2012.919,653.031,1651.090,1931.698,,,
|
||||
154,1e101ecac1,2026-09-27,2998,Add BON8 support (#2998),1975.804,4082.375,11658.542,3192.828,3758.141,907.029,444.920,556.470,6844.698,849.276,1977.153,649.181,1645.306,1920.836,,,
|
||||
155,9e1a09eec0,2026-09-28,5594,Name the key type when rejecting non-string CBOR/MessagePack map keys (#5594),2006.582,4151.784,11788.532,3156.156,3845.052,915.647,454.027,557.846,6814.282,864.094,2021.072,654.095,1663.051,1947.078,,,
|
||||
156,fc03b9912e,2026-09-28,5597,"Look up the locale decimal point at conversion time, not lexer construction (#5597)",2020.431,4172.916,12716.958,3196.958,3909.774,910.001,449.314,547.334,6900.968,852.306,2048.019,665.843,1696.937,1982.586,,,
|
||||
157,5b9ffae8bb,2026-09-30,5616,Move the float conversion chain out of the lexer (#5616),1992.332,4167.328,12638.573,3212.515,3842.885,906.649,446.941,539.674,6952.672,839.042,2021.057,695.813,1684.689,1967.216,,,
|
||||
158,d268eaa693,2026-09-30,5617,Convert floats with Eisel-Lemire when std::from_chars is unavailable (#5617),1987.608,4086.125,11507.062,3170.013,3830.425,898.856,445.077,542.854,6919.568,839.210,2021.918,666.925,1701.466,1951.211,,,
|
||||
159,65af260117,2026-09-30,5609,Move instead of deep-copy ordered_json values when an object grows (#5609),1998.981,4134.057,11592.855,3192.779,3863.005,904.702,446.575,539.685,6850.886,840.845,2035.646,680.331,1682.755,1968.744,,,
|
||||
160,6a8a7735ed,2026-09-30,5614,Do not throw in contains() for an empty array reference token (#5614),2008.447,4144.024,11612.176,3165.468,3842.060,905.045,443.941,539.755,6846.042,846.248,1998.713,669.752,1684.717,1953.487,,,
|
||||
161,0050d0f7a4,2026-09-30,5637,Share one nesting depth limit between all bounded descents (#5637),2021.078,4170.581,11589.886,3224.963,3937.021,906.411,448.033,541.177,6911.391,848.641,2040.978,670.005,1703.593,1984.639,,,
|
||||
162,68beba727c,2026-09-30,5679,Fix from_json() for enums with underlying type bool (#5679),1986.468,4139.033,11632.833,3201.351,3798.006,888.464,438.471,535.903,6843.110,836.030,1996.109,685.053,1672.430,1940.598,,,
|
||||
163,fc4c9c3446,2026-09-30,5680,Fix clear() to also reset the subtype of a binary value (#5680),1972.561,4094.867,11540.157,3155.722,3833.925,893.243,445.764,539.739,6848.562,843.068,2016.293,664.788,1685.759,1965.342,,,
|
||||
164,678fd3017b,2026-09-30,5681,Fix element path for map/unordered_map JSON_DIAGNOSTICS errors (#5681),2014.783,4164.471,11563.614,3219.865,3891.917,892.727,445.945,542.044,6900.807,844.422,2034.323,669.901,1688.051,1981.601,,,
|
||||
165,6d7845d207,2026-09-30,5683,Fix deprecated json_pointer/string operator== warning in value() (#5683),1965.197,4105.789,11501.364,3157.544,3800.289,898.122,445.399,539.685,6900.433,834.541,2000.133,652.354,1670.945,1960.876,,,
|
||||
166,42f89e3130,2026-09-30,5684,Let to_json(std::optional<T>) propagate exceptions from T's to_json (#5684),2016.899,4156.430,11476.489,3216.315,3895.245,908.714,444.300,541.764,6923.422,839.459,2018.934,672.859,1689.306,1987.428,,,
|
||||
167,6218aa212b,2026-09-30,5687,Throw std::length_error for operator[](SIZE_MAX) instead of corrupting the array (#5687),1989.158,4149.156,11547.229,3193.015,3845.187,905.308,446.389,541.290,6853.266,843.028,2037.245,661.213,1681.390,1966.649,,,
|
||||
168,1151826508,2026-09-30,5691,Take diff()'s fast path unless the object type reorders members (#5691),1991.280,4147.341,11570.312,3171.182,3847.333,904.510,441.250,539.803,6885.776,836.303,2018.693,665.307,1685.990,1970.057,,,
|
||||
169,e444a66276,2026-09-30,5693,Copy values before inserting an initializer list into an array (#5693),2000.774,4175.507,11546.979,3189.357,3841.169,897.455,442.384,539.493,6839.688,836.213,2014.519,667.390,1685.418,1968.991,,,
|
||||
170,bfea6f36d3,2026-09-30,5694,Fix to_msgpack() reading the inactive number union member (#5694),1997.465,4144.279,11549.781,3224.287,3855.120,899.475,441.995,539.924,6903.776,839.550,2019.396,664.487,1688.249,1954.211,,,
|
||||
171,5b11a0282c,2026-09-30,5697,Exchange the CustomBaseClass subobject in basic_json::swap() (#5697),1987.983,4074.349,11483.114,3174.632,3841.604,893.256,438.279,535.885,6866.641,834.328,1996.396,660.828,1676.300,1936.210,,,
|
||||
172,44a88d85be,2026-09-30,5698,Fix NLOHMANN_JSON_SERIALIZE_ENUM_STRICT's from_json message (#5698),1972.237,4125.945,11373.917,3158.716,3810.039,890.097,438.075,534.577,6867.432,842.045,2028.150,664.206,1681.353,1936.231,,,
|
||||
173,bfe0f32d71,2026-09-30,5699,Fix std::terminate and null pointer access in input_stream_adapter (#5699),2014.371,4159.779,11667.416,3200.425,3876.135,911.716,448.788,543.198,6932.657,852.397,2056.197,668.764,1699.573,1984.479,,,
|
||||
174,4bb1b14b06,2026-09-30,5702,Trim the compiler-appended NUL from wide/UTF string literals too (#5702),1979.723,4105.685,11603.562,3180.932,3846.698,906.188,443.969,534.534,6837.479,840.588,2006.043,654.851,1672.289,1965.408,,,
|
||||
175,5bd766aa50,2026-09-30,5703,Move to_bson's binary subtype check into calc_bson_sizes (#5703),1999.606,4183.386,11588.646,3192.771,3844.425,900.169,446.795,541.406,6888.114,847.107,2022.637,663.480,1686.702,1974.777,,,
|
||||
176,6ae17630a4,2026-09-30,5705,"Reject integral keys for contains(), find(), and count() at compile time (#5705)",2000.405,4157.120,11551.656,3197.417,3891.646,903.558,448.544,541.553,6914.203,848.561,2042.578,663.661,1691.910,1974.341,,,
|
||||
177,7fd6895788,2026-09-30,5706,Hide a discarded container's content from the parser callback (#5706),1971.987,4075.362,11463.219,3164.909,3797.453,889.534,443.974,535.026,6857.323,835.793,2025.343,651.970,1687.670,1951.428,,,
|
||||
178,66877675b1,2026-09-30,5719,"Check the iterator range for binary values in basic_json(first, last) (#5719)",1970.369,4104.886,11534.635,3168.601,3796.291,897.271,444.655,538.917,6826.990,842.445,2016.962,650.099,1673.940,1953.693,,,
|
||||
179,2ea6d8c127,2026-09-30,5720,Require the found key to equal the looked-up key when comparing objects (#5720),2015.556,4188.886,11567.125,3251.890,3863.818,903.970,448.691,540.422,6912.255,843.774,2044.479,653.832,1676.634,1951.959,,,
|
||||
180,67435c9c7e,2026-09-30,5721,Give a deep copy its type only after its container exists (#5721),1994.257,4160.658,11600.553,3218.367,3880.128,900.769,449.260,541.607,6899.448,841.635,2043.909,666.759,1694.646,1974.861,,,
|
||||
181,6fc0d501f3,2026-09-30,5610,Move the user-defined string literals to <nlohmann/json_literals.hpp> and add JSON_NO_AUTOMATIC_UDLS (#5610),2021.715,4187.888,11647.594,3209.388,3925.060,911.591,450.961,544.303,6975.265,845.109,2049.853,670.295,1697.019,1987.428,,,
|
||||
182,fdcc569eee,2026-09-30,5692,Use only documented StringType members in json_pointer (#5692),1965.264,4147.273,11378.188,3159.364,3787.758,889.399,447.397,535.062,6809.698,835.116,2015.202,656.241,1689.072,1955.238,,,
|
||||
183,6a073dbae4,2026-09-30,5695,Give operator>> a strong exception-safety guarantee (#5695),2010.979,4211.982,11698.218,3205.401,3897.172,898.499,445.961,545.225,6898.870,847.042,2051.316,664.716,1706.401,1981.247,,,
|
||||
184,3b6ae43c53,2026-09-30,5598,Add JSON_DISABLE_TUPLE_REFERENCE_CONVERSION to fix std::tuple conversions (#5598),2025.122,4195.468,11682.199,3204.529,3924.068,904.766,448.209,544.669,7041.276,849.103,2047.488,665.592,1695.987,1984.755,,,
|
||||
185,7d7055ec50,2026-09-30,5723,Fix stack overflow converting deep values between specializations (#5723),1985.310,4117.099,11457.052,3157.591,3832.175,895.910,442.225,535.237,6864.375,833.653,2001.760,679.826,1674.819,1956.998,,,
|
||||
186,35802e78d6,2026-09-30,5735,Remove dead Makefile targets; document macro_builder; tidy serve_header (#5735),2004.498,4163.065,11590.594,3184.810,3902.229,906.494,447.394,539.542,6923.969,845.596,2044.457,666.187,1692.019,1977.030,,,
|
||||
187,c261578431,2026-09-30,5730,Deduplicate binary reader/writer helpers and fix stale comments (#5730),1968.723,4154.789,11441.718,3160.367,3870.578,889.545,443.139,535.314,6850.886,837.281,2024.650,660.842,1691.628,1978.000,,,
|
||||
188,1d675cdb46,2026-09-30,5733,Fix CI jobs that check less than they claim; move arm64 to GitHub (#5733),1995.704,4206.185,11691.125,3227.622,3966.104,909.748,449.770,541.566,6951.938,852.506,2009.592,663.701,1686.265,1983.285,,,
|
||||
189,a32f61eb98,2026-09-30,5678,Fix update() and merge_patch() when the argument is *this or one of its members (#5678),2014.810,4157.101,11636.135,3210.326,3924.659,899.344,448.133,541.371,6913.401,841.487,2038.263,667.515,1697.503,1980.686,,,
|
||||
190,18dd5663b0,2026-10-01,5548,Diff deeply nested values without recursing per nesting level (#5548),1990.931,4152.500,11469.697,3204.740,3985.593,903.248,448.981,540.974,6929.740,847.493,2040.504,665.352,1698.903,1981.438,,,
|
||||
191,3926fcaac3,2026-10-01,5729,"Deduplicate serializer dump code; fix stale includes, docs, and lint (#5729)",1999.556,4178.489,11581.000,3208.657,3876.755,891.669,452.445,538.525,6893.078,846.721,2042.010,662.154,1689.653,1975.503,,,
|
||||
192,cff0a61369,2026-10-01,5731,Share DOM SAX position handling; fix stale parser and lexer comments (#5731),2017.231,4112.604,11588.291,3157.047,3890.343,902.329,458.713,539.539,7020.568,847.995,2073.873,654.562,1696.823,1978.381,,,
|
||||
193,e400780533,2026-10-01,5745,Re-amalgamate single_include (#5745),1980.338,4100.659,11418.854,3166.896,3835.432,885.298,452.886,538.053,6888.203,824.666,2031.410,650.846,1668.952,1949.107,,,
|
||||
194,6aec1a085f,2026-10-02,5677,Report BON8 input that ends after a UTF-8 lead byte as truncated (#5677),2003.321,4099.066,11614.364,3159.029,3849.857,899.995,459.542,539.436,6904.474,843.221,2071.503,652.303,1685.702,1972.556,,,
|
||||
195,4d46bce4e1,2026-10-02,5750,Fix CI on develop (#5750),1962.685,4025.677,11277.718,3103.052,3785.213,894.610,448.583,533.887,6870.062,834.856,2020.231,658.339,1674.874,1954.242,,,
|
||||
196,63c10a51fc,2026-10-02,5638,"Review and extend the documentation, and check it in CI (#5638)",1968.954,4036.851,11425.135,3104.359,3797.852,902.519,451.067,537.668,6910.375,852.438,2043.889,674.938,1701.314,1971.711,,,
|
||||
197,6d0867a85f,2026-10-02,5751,Make comparisons with scalars noexcept only when the conversion is (#5751),2008.360,4091.453,11376.562,3144.575,3820.110,903.850,455.980,538.035,6851.885,841.549,2010.128,667.182,1690.586,1970.957,,,
|
||||
198,d11e89471b,2026-10-04,5606,Assert on missing array indices in const operator[] and document the JSON pointer case (#5606),2000.121,4075.695,11475.520,3139.456,3837.211,900.437,453.703,538.895,6921.432,845.064,2027.417,663.969,1679.148,1964.082,,,
|
||||
199,df27cc3d4c,2026-10-04,5682,Add scalar-on-left overloads for legacy discarded comparisons in C++20 (#5682),2010.838,4092.432,11495.625,3125.726,3873.167,911.281,456.807,538.386,6911.630,844.451,2033.630,688.219,1691.407,1971.697,,,
|
||||
200,6f2048cd5d,2026-10-04,5685,Accept lvalues in ordered_map::emplace's value parameter (#5685),1999.816,4095.006,11445.740,3136.685,3924.146,918.692,458.336,542.423,6968.520,848.783,2037.096,667.772,1708.274,2002.449,,,
|
||||
201,0d01d6ae90,2026-10-04,5686,Classify leaves with operator<=> itself past the nesting bound (#5686),1983.320,4116.981,11466.250,3192.969,3923.208,914.596,456.625,539.558,6975.537,849.252,2056.035,701.221,1716.493,1983.908,,,
|
||||
202,b730946432,2026-10-04,5689,Fix key types convertible to std::string_view breaking lookups (#5689),1990.288,4060.487,11377.709,3107.537,3803.857,892.191,451.727,538.045,6896.480,844.989,2018.884,658.649,1676.566,2023.638,,,
|
||||
203,49cd427196,2026-10-04,5690,"Copy-construct the base class of a deep copy's elements, not assign it (#5690)",1983.320,4033.156,11333.843,3138.547,3882.878,894.785,454.473,538.337,6918.619,841.205,2072.151,655.193,1693.871,1977.288,,,
|
||||
204,756b28c2b8,2026-10-04,5696,Keep a NUL byte ending a // comment as the end of input (#5696),1985.931,4099.331,11579.875,3148.560,3872.422,896.276,451.436,536.774,6901.156,845.631,2014.820,648.054,1685.199,1971.762,,,
|
||||
205,1edf0ef041,2026-10-04,5700,"Fix value(json_pointer, default) aborting under JSON_NOEXCEPTION (#5700)",1987.233,4076.133,11442.625,3124.099,3888.688,898.266,454.349,539.423,6950.140,852.803,2030.279,654.586,1691.751,1978.197,,,
|
||||
206,a212d3b2e4,2026-10-04,5722,Preserve the object comparator's state in a deep copy past the nesting bound (#5722),2000.138,4113.471,11391.854,3151.006,3866.904,905.695,455.384,539.504,6929.818,842.213,2029.619,674.438,1697.044,1983.856,,,
|
||||
207,1df1e8a845,2026-10-04,5591,Make cross-string-type basic_json conversion explicit without implicit conversions (#5591),2000.533,4107.994,11370.989,3160.854,3881.635,897.877,455.201,540.307,6927.167,840.130,2053.458,664.118,1697.618,1982.876,,,
|
||||
208,38a2db260c,2026-10-04,5728,Remove dead metaprogramming and duplicated code in traits and pointers (#5728),1971.450,4040.828,11319.270,3109.521,3819.505,903.606,451.137,538.725,6825.640,843.951,2016.652,663.160,1684.596,1958.896,,,
|
||||
209,c5650eaa3c,2026-10-04,5704,Reject malformed UTF-16/UTF-32 units in wide-string input (#5704),2006.689,4133.594,11469.209,3180.930,3881.633,902.924,456.572,540.557,6992.385,850.474,2025.267,652.367,1680.025,1957.468,,,
|
||||
210,40021f38fb,2026-10-04,5589,Add basic_json::as_base_class and document name conflicts with custom base classes (#5589),2012.673,4147.193,11453.250,3167.448,3892.542,910.149,457.238,541.642,6998.084,852.247,2049.759,652.868,1688.229,1972.508,,,
|
||||
211,73e9eae3c1,2026-10-04,5746,Add an error_handler parameter for UTF-8 to the binary readers and writers (#5746),2013.845,4130.237,11456.041,3135.688,3818.956,892.111,449.408,538.308,6825.213,835.872,1495.468,697.054,1679.760,1970.285,,,
|
||||
212,d8d47be4a5,2026-10-04,5754,Fix CI on develop after merging the ready-to-merge PRs (#5754),2013.191,4119.948,11573.656,3173.029,3941.703,912.201,459.208,541.264,7013.364,848.908,1514.681,699.273,1685.391,1984.652,,,
|
||||
213,6b4b825af2,2026-10-04,5607,Handle numbers that do not fit narrow number types in the binary readers (#5607),2009.190,4044.127,11362.677,3127.688,3827.841,892.131,449.386,534.731,6915.360,829.562,1487.640,697.206,1688.237,1952.157,,,
|
||||
214,8c1f60a45e,2026-10-04,5600,Store maps with enum keys as objects (opt-in) (#5600),2008.560,4128.059,11523.011,3187.763,3843.177,912.520,456.427,537.514,6859.010,839.685,1501.515,696.508,1688.848,1968.910,,,
|
||||
215,c5a7a4b46d,2026-10-04,5688,"Add deprecated from_bon8/from_bjdata(ptr, len) overloads (#5688)",2030.310,4108.505,11412.907,3141.836,3899.435,904.756,455.298,541.069,6926.151,846.240,1504.193,700.820,1693.983,1987.713,,,
|
||||
216,23d3b373e1,2026-10-04,5755,Add JSON_DELETE_DEPRECATED_FUNCTIONS to delete the deprecated functions (#5755),2018.708,4106.015,11533.729,3134.945,3826.409,899.623,452.833,538.544,6846.443,830.555,1509.060,705.724,1692.819,1971.476,,,
|
||||
217,8a142bc436,2026-10-06,5764,"Fix CI on develop after #5600, #5607, and #5755 (#5764)",2017.533,4151.854,11526.334,3195.240,3884.953,907.457,456.697,540.114,6891.136,844.145,1517.241,699.051,1690.344,1972.104,,,
|
||||
218,5379e04ce4,2026-10-06,5761,Throw type_error.321 when serializing discarded values to binary formats (#5761),1999.156,4055.300,11427.521,3153.581,3836.060,891.927,455.413,540.938,6883.093,853.094,1510.099,701.888,1686.695,1982.806,,,
|
||||
219,0a365865f9,2026-10-06,5762,Make basic_json destruction allocation-free and non-recursive (#5762),2024.289,4081.646,10719.428,3112.958,3900.503,924.900,462.081,540.765,6965.453,850.019,1511.381,669.802,1620.269,1912.078,,,
|
||||
220,5ecb704f6b,2026-10-06,5592,Speedup; check for the expected separator before the lexer's token switch (#5592),1920.428,3801.979,10139.250,2891.862,3833.159,823.859,451.951,540.310,6885.672,843.570,1512.778,668.793,1608.501,1885.206,,,
|
||||
221,6d4543e743,2026-10-06,5767,Fix destroy() for ObjectTypes without reverse iteration (#5767),1929.030,3843.266,10232.541,2911.458,3926.867,830.030,450.002,542.043,6938.890,846.589,1515.211,675.264,1622.245,1904.006,,,
|
||||
222,9b179cee1e,2026-10-06,5770,Handle all value_t enumerators in has_no_children() (#5770),1931.275,3794.497,10155.125,2891.927,3871.831,829.432,446.176,535.126,6909.625,833.114,1498.945,677.571,1615.785,1884.043,,,
|
||||
223,69874e4544,2026-10-06,5760,Fix NUL bytes in UBJSON/BJData high-precision numbers (#5760),1924.896,3853.081,10247.750,2926.515,3872.041,835.227,453.025,541.002,6919.037,842.240,1521.169,674.487,1607.441,1880.884,,,
|
||||
224,162e13b86f,2026-10-06,5758,Add with_*_t alias templates to create basic_json types with changed template parameters (#5758),1938.268,3842.126,10289.968,2914.104,3962.414,834.967,455.536,543.630,6969.266,850.082,1530.064,678.054,1635.303,1916.763,,,
|
||||
225,21a69230bd,2026-10-06,5585,Create a value before giving it its type (#5585),1918.165,3829.354,10247.656,2914.619,3874.909,832.287,451.252,543.791,6873.995,839.514,1521.088,699.604,1615.742,1894.449,,,
|
||||
226,ff6f3d7d4a,2026-10-07,5766,Reject nested indefinite-length CBOR string chunks (#5766),1926.074,3868.810,10256.823,2919.802,3957.807,832.129,457.241,543.640,7024.745,847.770,1522.612,705.623,1634.212,1918.402,,,
|
||||
227,1c754cfe31,2026-10-07,5701,Copy a pair-shaped array value under JSON_BRACE_INIT_COPY_SEMANTICS (#5701),1930.652,3828.195,10263.927,2921.570,3901.404,832.628,455.652,541.701,6909.037,843.563,1512.309,704.354,1623.254,1909.917,,,
|
||||
228,24dd7c63f0,2026-10-07,5777,Re-amalgamate after #5740 (#5777),1908.632,3833.930,10278.146,2905.443,3935.422,838.465,454.491,545.605,6905.047,839.087,1519.816,709.223,1618.643,1886.706,,,
|
||||
229,30e542e52a,2026-10-07,5776,Declare the namespace-scope constants in to_chars.hpp inline (#5776),1934.934,3823.724,10229.636,2916.698,3929.565,829.102,452.279,543.038,6951.995,837.059,1524.049,720.722,1619.823,1903.938,,,
|
||||
230,367336c83d,2026-10-07,5779,Fix CI on develop after #5585 (#5779),1928.921,3780.927,10153.395,2883.604,3877.750,824.488,451.999,543.662,6927.395,835.495,1506.387,694.058,1622.903,1907.732,,,
|
||||
231,069ace74af,2026-10-07,5707,"Round-trip BJData ND-array annotations exactly (single precision, key order) (#5707)",1937.387,3843.716,10184.302,2923.323,3936.570,827.610,456.123,543.169,6907.756,847.020,1515.229,696.202,1626.001,1901.142,,,
|
||||
232,43fe8928e1,2026-10-07,5781,Stop binary writers overflowing the stack on deep values (#5781),1961.046,3868.274,10300.573,2899.792,3982.526,845.594,461.395,543.298,7059.093,846.696,1522.728,697.717,1623.846,1921.370,,,
|
||||
233,a5f5d3059b,2026-10-07,5772,Make std::hash<basic_json> consistent with operator== for numbers (#5772),1949.220,3857.159,10170.427,2890.052,3981.349,840.234,459.334,541.947,6953.786,843.495,1509.713,703.339,1627.086,1911.653,,,
|
||||
234,a269794db7,2026-10-08,5782,Use MSVC intrinsics for full multiplication (#5782),1931.869,3817.742,10159.666,2902.820,3903.263,840.740,455.827,540.621,6884.562,843.272,1513.776,702.028,1614.459,1901.008,,,
|
||||
235,69a0c1b82c,2026-10-09,5328,Avoid allocating temporary basic_json for cbor and msgpack object keys (#5328),1909.579,3777.560,10065.682,2852.732,3897.659,833.289,459.856,540.631,6882.354,833.998,1498.288,314.059,1609.343,1906.714,,,
|
||||
236,374dfe4f0f,2026-10-09,5791,Keep converted object keys alive while writing UBJSON and BJData (#5791),1911.274,3827.188,10159.553,2886.568,3890.388,833.632,459.800,542.649,6954.547,838.507,1509.324,314.357,1613.655,1892.838,,,
|
||||
237,44e8597701,2026-10-09,5792,Flatten deeply nested values without recursing per nesting level (#5792),1940.103,3811.779,10139.396,2865.050,3874.896,835.001,459.686,544.065,6866.943,836.862,1496.298,314.617,1614.837,1891.741,,,
|
||||
238,2913e96433,2026-10-09,5793,Unflatten in time and memory linear in the pointer depth (#5793),1908.453,3785.099,10262.147,2878.961,3920.657,845.619,459.806,543.998,6874.813,832.659,1486.901,312.175,1589.620,1863.981,,,
|
||||
239,84ee12a67c,2026-10-09,5797,Make UTF8_ACCEPT/UTF8_REJECT inline variables to avoid TU-local exposure in modules (#5797),1922.691,3792.849,10162.656,2871.562,3887.719,836.308,456.522,542.577,6912.807,840.369,1497.447,313.683,1609.988,1899.591,,,
|
||||
240,1649d9eda4,2026-10-11,5783,Use and extend the detail helpers to remove duplicated code (#5783),1916.258,3804.242,10297.344,2913.118,3847.662,836.519,453.270,538.750,6953.015,832.774,1506.068,324.715,1596.974,1875.878,,,
|
||||
241,2cca04ae6f,2026-10-11,5800,Report one-character non-numeric array indices like longer ones (#5800),1932.327,3803.750,10135.438,2881.041,3894.622,840.016,458.569,538.037,6842.948,829.444,1499.722,324.811,1607.194,1875.851,,,
|
||||
242,74a03dec84,2026-10-11,5802,Throw type_error.321 for discarded values in to_bon8 (#5802),1924.695,3814.854,10084.239,2873.180,3848.498,839.406,450.575,534.181,6893.005,834.300,1503.369,324.389,1607.323,1887.871,,,
|
||||
243,e8b747e4bc,2026-10-11,5808,Re-amalgamate single_include after #5795 and #5806 (#5808),1937.995,3840.622,10221.990,2896.024,3885.568,834.394,458.874,539.771,6906.182,839.793,1517.689,324.800,1609.838,1890.885,,,
|
||||
244,40a62947d3,2026-10-12,4965,support JSON Merge Patch (RFC 7396) diff creation (#4965),1932.021,3822.188,10248.416,2924.560,3980.331,842.462,459.010,540.237,6978.526,838.941,1529.508,326.435,1636.153,1917.472,,,
|
||||
245,f23830b65e,2026-10-13,5809,Derive the lexer position lazily for seekable input (#5809),1814.075,3368.028,9974.755,2807.532,3943.229,647.639,457.018,551.206,6954.166,843.355,1522.762,315.716,1618.953,1903.816,,,
|
||||
246,aa9620fb15,2026-10-13,5810,Skip the indentation after a newline 8 bytes at a time (#5810),1719.629,2959.344,10139.771,2799.555,3939.292,592.867,465.821,545.858,6968.068,849.167,1519.774,315.385,1629.981,1907.253,,,
|
||||
247,e839bbd1c0,2026-10-13,5813,"Export client-facing headers from json.hpp for IWYU / include-cleaner, and check clients in CI (#5813)",1725.742,2949.070,10136.603,2821.591,3919.927,589.957,463.642,544.851,6987.427,843.151,1517.562,314.425,1619.671,1903.613,,,
|
||||
248,5b4c8f9b00,2026-10-14,5738,"Speed up the lexer: own float parser, string scan, and \u table (#5738)",1615.668,2934.565,8763.651,2794.503,3928.286,559.107,374.921,516.391,6937.140,815.776,1513.238,325.043,1625.226,1912.905,,,
|
||||
249,91a7a94cc6,2026-10-14,5634,"Write doubles with the shortest digits (Żmij), digits in registers (#5634)",1613.126,2929.599,8708.599,2783.954,3874.248,548.449,363.632,468.127,2421.176,745.466,1511.406,323.743,1614.195,1900.392,,,
|
||||
250,a6e9785ab6,2026-10-15,5831,Look up the key only once in the callback parser's key() (#5831),1589.309,2938.557,8798.823,2767.872,3882.154,547.301,364.257,467.833,2395.851,744.716,1506.830,316.192,1623.771,1899.458,,,
|
||||
251,0c4e7c103c,2026-10-15,5834,Make flatten() linear for ordered_json (#5834),1625.754,2936.203,8755.088,2793.081,3879.740,557.529,366.745,468.359,2418.388,746.210,1524.325,315.954,1614.677,1898.544,,,
|
||||
252,0a4b3a84ee,2026-10-15,5836,"Speed up JSON pointer parsing, formatting, comparison and lookup (#5836)",1622.914,2915.901,8819.073,2783.990,3922.758,558.429,366.216,470.019,2427.606,747.168,1526.881,316.972,1625.611,1912.601,,,
|
||||
253,6ba53e63dd,2026-10-15,5833,Speed up array-to-container from_json (#5833),1626.155,2920.747,8777.989,2782.870,3988.206,560.154,367.695,469.892,2427.262,749.301,1529.474,316.399,1631.810,1915.217,,,
|
||||
254,ca7740fef2,2026-10-15,5837,Move elements when converting rvalue containers to JSON (#5837),1615.747,2928.778,8765.792,2773.062,3926.456,561.034,367.498,469.807,2424.344,748.423,1523.215,316.339,1624.374,1894.455,,,
|
||||
255,4530d9681c,2026-10-15,5832,Fix quadratic parent updates for ordered_json with JSON_DIAGNOSTICS (#5832),1618.937,2911.378,8794.094,2763.191,3886.974,555.789,366.475,469.275,2415.231,746.755,1512.590,315.856,1618.226,1899.284,,,
|
||||
256,91869983a0,2026-10-15,5840,Make the value lifecycle inline-friendly (#5840),1595.075,2832.274,8420.390,2690.050,3876.841,555.209,366.118,469.783,2424.335,747.931,1485.914,314.048,1549.787,1775.823,,,
|
||||
257,6a27b9acb2,2026-10-15,5838,Construct remaining hot-path exceptions out of line so core functions inline (#5838),1589.535,2824.360,8466.755,2699.690,3888.990,557.917,364.879,471.601,2422.995,746.543,1498.371,314.978,1539.656,1797.752,,,
|
||||
258,4f11512641,2026-10-15,5835,"Speed up container destruction, iterator access and diff() (#5835)",1515.750,2714.756,8639.213,2574.698,3805.860,561.827,366.793,469.680,2421.769,748.727,1383.744,317.248,1446.525,1705.789,,,
|
||||
259,ed86019a21,2026-10-15,5839,Move binary reader error construction out of line (#5839),1507.907,2766.774,8597.870,2622.289,3767.638,553.026,362.644,468.482,2408.731,744.936,1362.080,324.833,1445.531,1703.216,,,
|
||||
260,6261d1e432,2026-10-15,5842,Construct the JSON Patch exceptions out of line (#5842),1532.015,2756.867,8670.677,2617.989,3869.133,558.865,365.834,469.932,2435.279,750.295,1380.628,327.010,1453.340,1705.232,,,
|
||||
261,ce28c722bc,2026-10-15,5815,Allow the same type for number_integer_t and number_unsigned_t (#5815),1533.045,2775.807,8543.755,2615.412,3776.721,553.127,365.866,471.174,2433.384,745.309,1372.372,328.405,1452.848,1716.649,,,
|
||||
262,91b9ee2602,2026-10-15,5829,Update cppcheck to 1.5.2 (Cppcheck 2.20) and fix its new findings (#5829),1516.450,2748.961,8571.521,2599.870,3807.744,557.303,367.220,472.209,2421.389,743.889,1379.405,326.087,1451.926,1710.506,,,
|
||||
263,dcb96e82fb,2026-10-15,5822,Escape characters below 0x60 from a table straight into the write buffer (#5822),1525.777,2734.963,8524.771,2588.289,3790.726,557.907,360.057,463.574,2430.626,743.382,1375.816,325.308,1439.947,1695.307,,,
|
||||
264,b41228c227,2026-10-15,5843,Fix AppVeyor failures from the Zmij double writer (#5843),1497.922,2690.614,8406.906,2582.482,3726.195,548.374,352.932,459.663,2398.953,737.639,1347.507,322.827,1429.640,1682.775,,,
|
||||
265,4da73dc5ff,2026-10-15,5858,Fix compiler warnings on develop from the API performance stack (#5858),1523.138,2731.825,8474.073,2593.149,3782.769,553.758,359.180,462.915,2380.246,739.049,1346.755,324.909,1441.408,1698.043,,,
|
||||
266,5683f5e024,2026-10-15,5859,Define less_general() only without three-way comparison (#5859),1504.689,2739.172,8603.693,2605.159,3797.057,560.213,358.865,464.429,2423.456,742.207,1374.000,326.702,1447.488,1712.379,,,
|
||||
267,cd6b428ef0,2026-10-16,5860,Fix CI failures on develop from the API performance stack (#5860),1510.160,2732.695,8564.510,2603.242,3810.518,556.015,362.409,466.047,2437.364,745.153,1377.439,325.753,1444.892,1699.255,,,
|
||||
268,cc8334113c,2026-10-19,5866,Do not use Qt's keyword macros as identifiers (#5866),1498.858,2732.644,8535.328,2587.258,3787.993,548.267,362.607,464.487,2403.147,735.633,1368.831,323.997,1442.709,1686.963,,,
|
||||
269,4da932f518,2026-10-19,5828,Make parsing from std::istream and FILE* fast (#5828),1499.289,2723.605,8397.787,2597.237,1956.330,553.182,363.501,458.898,2397.342,733.054,1362.816,320.346,1429.314,1698.294,,,
|
||||
270,122d718330,2026-10-21,5620,"Add json_document and json_view: node index, parser, and document (#5620)",1520.651,2751.099,8527.135,2588.494,1994.466,560.384,362.257,461.917,2393.611,741.198,1362.167,328.620,1441.211,1691.238,230.700,389.375,976.277
|
||||
271,43e97b629b,2026-10-21,5622,"Add element access, iteration, values, and JSON pointers to json_view (#5622)",1493.875,2687.307,8383.354,2567.078,1986.311,547.934,353.938,462.380,2400.331,737.098,1374.560,322.012,1445.504,1686.421,231.353,386.679,958.441
|
||||
272,4c3a3eb5b5,2026-10-21,5624,Add dump() and comparisons to json_view (#5624),1502.926,2714.747,8522.161,2608.565,2001.856,552.014,359.510,462.656,2393.110,732.091,1366.524,324.313,1442.119,1682.564,228.836,393.082,976.976
|
||||
273,3ff37ead75,2026-10-21,5628,Scan json_view strings with SIMD and index large objects (#5628),1514.580,2728.619,8406.562,2609.758,2041.176,556.017,357.330,462.573,2383.158,733.939,1368.057,324.391,1442.711,1700.884,177.833,367.806,950.071
|
||||
274,823eee3b59,2026-10-21,5630,"Add editable json_documents: set, push_back, insert, and erase (#5630)",1498.134,2754.810,8537.062,2588.474,1994.441,556.670,353.931,463.646,2392.987,740.023,1357.930,324.129,1441.622,1698.022,181.404,376.470,962.253
|
||||
275,4971200b54,2026-10-21,5632,Add images of json_documents: save() and load() (#5632),1494.231,2681.211,8425.834,2543.276,1984.849,548.146,354.762,460.440,2414.747,734.679,1363.841,321.349,1421.806,1670.134,177.777,368.631,949.292
|
||||
276,4155e2938f,2026-10-21,5633,Write json_view's dump() without a call or conversion per token (#5633),1500.247,2712.357,8612.193,2597.211,2012.860,558.559,359.889,462.371,2412.896,739.048,1372.456,324.070,1441.546,1697.571,180.320,371.514,954.088
|
||||
277,08d7fbb0a1,2026-10-21,5874,Read FILE* input with std::fgetc under MemorySanitizer (#5874),1543.124,2758.211,8565.730,2584.453,2046.255,558.522,358.865,464.542,2421.435,743.715,1374.005,324.687,1462.572,1700.819,180.714,372.601,965.361
|
||||
278,0cbe95ffa2,2026-10-21,5824,"Speed up writing CBOR and MessagePack, above all integer arrays (#5824)",1501.550,2706.534,8707.120,2584.807,2039.728,551.688,360.692,466.024,2397.182,742.777,1361.847,201.488,1429.223,1682.436,178.641,371.038,946.389
|
||||
279,bd5227c2ec,2026-10-21,5805,Fix silent wrong results for custom number types (#5805),1511.036,2733.325,8786.406,2588.906,2000.483,553.456,360.458,465.989,2398.381,743.338,1370.524,201.168,1444.051,1701.345,179.776,372.557,954.733
|
||||
280,e13e976801,2026-10-21,5851,Accumulate number digits while scanning them (#5851),1501.737,2667.570,7762.365,2523.289,1987.518,545.368,359.336,462.056,2407.652,739.226,1368.104,200.632,1440.390,1688.117,178.721,374.278,956.353
|
||||
281,5e13f834c1,2026-10-21,5852,Copy the text of float tokens only when a SAX handler asks for it (#5852),1512.318,2655.312,7314.354,2515.044,2019.288,547.993,362.038,463.788,2410.262,745.839,1364.898,208.969,1450.422,1713.902,179.198,371.996,968.699
|
||||
282,e9970066c5,2026-10-21,5853,"Scan strings with SSE2, SSSE3, or NEON (#5853)",1488.705,2654.404,7339.589,2551.050,2015.716,486.719,341.381,475.591,2434.369,756.973,1376.754,208.797,1449.981,1706.044,182.358,379.153,968.355
|
||||
283,fa37b952df,2026-10-21,5854,Match literals without a stack array and keep parser states in bytes (#5854),1471.894,2619.164,7285.000,2485.883,1949.380,471.534,347.785,475.287,2413.552,751.487,1374.254,207.522,1443.177,1699.611,181.643,377.971,977.268
|
||||
284,52fecc1fab,2026-10-21,5855,Move object keys into the value when parsing (#5855),1392.599,2628.688,7362.562,2485.293,1882.663,471.968,339.711,473.663,2414.903,751.376,1319.857,200.185,1448.057,1705.675,179.410,371.865,963.306
|
||||
285,6aefd8c662,2026-10-21,5878,Copy short printable-ASCII strings without starting the scanner (#5878),1399.384,2664.401,7232.557,2535.425,1922.431,470.185,320.230,418.440,2446.082,696.786,1317.889,201.955,1447.217,1701.135,180.860,376.217,968.215
|
||||
286,7c26e99ac5,2026-10-21,5879,Copy ASCII strings in the view's dump with ensure_ascii (#5879),1361.839,2610.182,7187.115,2471.708,1853.592,464.274,313.821,414.316,2388.840,687.851,1318.253,200.399,1434.986,1697.487,178.601,368.595,947.799
|
||||
287,3e031b06a5,2026-10-21,5876,"Use standard library helpers where available, with C++11 fallbacks (#5876)",1381.599,2592.122,7336.719,2499.994,1848.434,467.895,315.257,415.788,2430.769,692.250,1311.164,200.424,1444.303,1698.311,180.149,374.484,961.091
|
||||
288,9bf531436f,2026-10-21,5861,"Speed up flatten(), unflatten(), diff() and patch() (#5861)",1379.301,2613.219,7170.433,2472.628,1853.035,467.161,315.217,412.303,2406.597,683.062,1298.512,198.681,1434.089,1682.912,177.511,368.116,947.255
|
||||
289,9855db81f3,2026-10-22,5881,Silence macro-to-enum for the endianness macros (#5881),1369.150,2613.547,7209.787,2476.232,1841.347,467.780,316.011,416.187,2415.504,686.920,1304.263,200.868,1441.243,1694.603,178.739,368.123,948.579
|
||||
290,aa0b371f7c,2026-10-23,5884,"Faster std::istream input: inline get-area path, binary reads, unbuffered streambufs (#5884)",1375.030,2569.362,7218.375,2484.425,1743.476,470.240,319.245,403.750,2436.034,679.759,1319.508,201.531,1443.354,1698.057,180.133,372.206,946.488
|
||||
291,86d5c56c54,2026-10-23,5886,"Speed up flatten(), unflatten(), diff() and patch() further (#5886)",1386.169,2622.331,7281.551,2495.923,1700.794,472.317,317.282,403.416,2409.097,682.507,1320.319,200.963,1444.908,1697.678,179.138,375.751,954.573
|
||||
292,dec0e9b749,2026-10-23,5883,"Write strings, scalars and indentation in dump() with fewer calls (#5883)",1383.235,2621.847,7151.412,2491.644,1732.469,473.034,211.016,288.685,2276.953,416.068,1318.490,200.574,1452.099,1701.256,180.064,372.324,960.583
|
||||
293,6fa14d8f95,2026-10-23,5885,Write binary formats through reserved sink space and number runs (#5885),1366.956,2600.914,7176.994,2465.343,1691.333,462.351,210.662,285.259,2301.553,417.589,1324.173,136.601,1429.240,1687.947,179.319,368.881,962.518
|
||||
294,0b924f5375,2026-10-23,5887,Split and print JSON pointers in one pass (#5887),1377.526,2597.394,7242.688,2464.445,1739.841,466.382,211.716,288.202,2319.771,418.288,1318.592,138.744,1441.983,1706.639,179.684,372.087,976.078
|
||||
295,e9c4fe3cdf,2026-10-24,5889,json_view: indented and ensure_ascii dumps through the fast writer (#5889),1393.007,2627.226,7248.287,2491.551,1769.642,469.976,211.665,291.327,2305.655,420.168,1319.431,139.577,1457.965,1712.927,182.274,377.741,983.284
|
||||
296,dd7686a269,2026-10-24,5888,"json_view: faster reading, indexing and C-stream parsing (#5888)",1382.444,2607.026,7161.365,2472.635,1701.277,468.438,209.963,287.564,2276.329,415.511,1311.194,137.875,1439.700,1696.646,177.624,367.131,977.802
|
||||
297,9c50bdd140,2026-10-24,5882,Make the DOM parser cheaper per container and per member (#5882),1392.673,2461.082,6068.625,2334.706,1696.950,475.550,209.313,291.776,2300.287,416.349,1317.581,138.194,1441.209,1707.720,178.751,367.339,978.031
|
||||
298,01139dc192,2026-10-24,5905,Silence an Infer false positive in json_view materialize (#5905),1381.470,2463.013,6078.010,2335.216,1709.088,475.718,211.023,291.212,2275.302,418.098,1320.441,137.572,1443.434,1696.436,175.969,365.658,975.272
|
||||
299,fe5e401870,2026-10-25,5901,Consolidate duplicated detail helpers and bodies (#5891) (#5901),1395.881,2462.765,6066.698,2327.708,1706.745,474.184,212.683,289.321,2283.842,417.657,1314.153,138.084,1442.796,1696.588,177.144,364.092,961.847
|
||||
300,3eae5680d6,2026-10-25,5902,"from_json: number-first dispatch for arithmetic types, loop for std::array (#5902)",1397.343,2477.060,6080.864,2340.781,1711.774,481.523,213.618,289.360,2289.503,417.517,1313.541,138.271,1440.822,1695.785,178.731,367.293,983.555
|
||||
301,2a56afc714,2026-10-25,5916,Fix VS 2015 build of the DOM parser (#5882) (#5916),1373.929,2476.139,6056.797,2341.890,1749.167,482.883,215.107,290.053,2292.495,417.441,1320.640,137.868,1445.227,1702.064,177.912,367.669,984.794
|
||||
302,d6431a9104,2026-10-26,5918,Throw out_of_range.411 for JSON Patch add into a null parent (#5917) (#5918),1371.635,2445.905,6017.636,2314.178,1696.447,478.134,210.996,287.397,2278.718,414.186,1291.197,137.374,1436.212,1682.197,175.790,361.130,962.070
|
||||
303,81d66291c5,2026-10-26,5358,Create objects for pointer tokens that cannot be array indices (#5358),1382.909,2465.649,6052.114,2332.556,1711.721,479.927,213.359,289.913,2289.412,417.201,1311.695,137.572,1437.168,1696.302,177.495,367.526,963.924
|
||||
304,d5da84249f,2026-10-26,5927,"Skip CBOR tags in front of map keys, validate indefinite text chunks, fix CBOR docs (#5927)",1374.553,2476.464,6076.834,2346.075,1744.224,483.375,211.423,291.148,2287.800,420.247,1320.015,137.369,1449.068,1704.785,177.459,365.004,963.908
|
||||
305,0c3570d44a,2026-10-26,5929,Validate the UBJSON/BJData container type marker for count 0; fix UBJSON docs (#5929),1381.462,2462.578,6055.183,2329.970,1713.086,484.962,210.683,290.024,2260.371,416.895,1319.093,137.782,1453.495,1706.801,177.031,361.025,962.952
|
||||
306,dc768a7d5d,2026-10-26,5930,Fix BSON binary subtype 0x02 and check the declared document size earlier (#5930),1386.856,2463.400,6054.255,2337.105,1746.441,485.425,214.508,290.954,2314.702,418.769,1325.164,139.255,1452.125,1718.313,179.005,367.327,977.054
|
||||
307,60107eda3f,2026-10-26,5931,"Read BJData ND-arrays of float16, restrict ND-array char to 0..127, correct BJData docs (#5931)",1389.051,2464.457,6049.084,2336.727,1710.473,483.159,213.007,288.990,2285.073,417.663,1317.537,137.893,1443.301,1697.126,178.706,364.051,962.202
|
||||
308,731f1b5bfb,2026-10-26,5919,"json_view: view_mode enum instead of bool Editable, node_kind for node::kind (#5919)",1381.664,2428.529,5978.713,2333.485,1746.571,479.163,211.036,288.957,2281.592,416.990,1308.904,137.486,1447.665,1691.427,175.453,363.704,963.371
|
||||
309,4cdfa6d0f4,2026-10-26,5920,json_view: no save() and load() on big-endian targets (#5920),1390.901,2477.841,6102.474,2337.925,1777.003,485.382,214.373,290.946,2303.147,421.178,1321.976,139.942,1446.726,1704.816,179.928,367.825,976.532
|
||||
310,5a2819c940,2026-10-26,5921,json_view: one SIMD macro set with the library (#5921),1393.409,2479.841,6073.011,2350.336,1785.087,485.658,214.651,292.044,2304.448,418.026,1326.212,138.942,1468.981,1719.505,179.174,368.704,982.764
|
||||
311,e5fe4ebdd2,2026-10-26,5922,json_view: from_json() of the macros reads views directly (#5922),1384.612,2467.078,6056.328,2337.309,1742.751,482.554,213.389,289.543,2299.118,417.521,1309.673,138.237,1448.628,1704.550,177.925,365.163,984.351
|
||||
312,9e67bfa115,2026-10-26,5923,json_view: the library's std conversions read views directly (#5923),1395.103,2482.517,6066.604,2350.538,1751.603,482.504,213.399,290.185,2306.188,420.406,1317.415,138.730,1444.367,1708.720,178.016,369.111,975.875
|
||||
313,21ec9bd801,2026-10-27,5915,json_view: fewer allocations when parsing small documents (#5915),1388.282,2469.118,6066.495,2340.391,1744.901,478.745,214.934,292.970,2309.264,422.842,1323.237,138.541,1454.151,1707.314,178.058,366.514,958.110
|
||||
314,2bb2feeef4,2026-10-27,5942,"Fix the red CI on develop (json_view pointer tokens, bson, from_json tests, Infer, IWYU) (#5942)",1391.981,2468.266,6068.495,2335.707,1751.527,482.908,214.285,291.291,2300.453,417.876,1328.089,138.010,1454.934,1701.845,178.250,367.182,964.917
|
||||
315,78a0687147,2026-10-27,5940,Strong exception guarantee for operator[](json_pointer) (#5940),1379.414,2467.492,6109.136,2335.309,1723.090,480.260,216.197,292.075,2313.798,415.444,1314.530,138.314,1449.629,1698.792,177.628,364.844,965.314
|
||||
316,091c10d4a5,2026-10-28,5936,Fix self-aliasing in json_pointer::operator/= and patch_inplace (#5936),1389.195,2462.409,6052.125,2321.091,1722.944,473.064,214.421,290.952,2279.997,416.589,1315.370,138.531,1437.996,1683.844,176.596,363.105,952.473
|
||||
317,54f6b3ef06,2026-10-28,5945,json_view: source positions in materialize() with JSON_DIAGNOSTIC_POSITIONS (#5945),1417.895,2496.591,6325.787,2377.105,1737.749,478.133,213.209,293.150,2304.971,422.648,1348.357,139.793,1490.556,1735.758,178.445,368.380,990.587
|
||||
318,0115bb47b3,2026-10-30,5965,Name the source and license of adapted code in the file comments (#5965),1378.289,2456.731,6043.011,2330.780,1711.965,470.960,212.371,290.798,2298.443,419.433,1323.072,137.982,1441.316,1690.457,176.197,363.182,977.928
|
||||
319,0b91f9ddd8,2026-10-30,5926,json_view: check_utf8 skips well-formed runs with the parser's string scan (#5926),1400.777,2488.449,6137.021,2359.856,1747.026,473.449,213.226,290.736,2320.524,420.950,1325.039,139.324,1452.907,1703.426,177.699,364.500,988.981
|
||||
320,ea03d601af,2026-10-30,5890,json_view: comparison without temporaries and a faster image float check (#5890),1388.958,2477.531,6127.547,2357.032,1781.238,477.111,216.144,293.938,2340.267,424.058,1337.149,139.387,1459.923,1723.919,,,
|
||||
321,755bb16d7a,2026-10-30,5966,Fix the red CI on develop: remove the duplicate is_editable in basic_json_view (#5966),1411.867,2497.560,6085.938,2326.880,1726.740,480.376,212.294,292.134,2312.521,420.608,1325.345,138.544,1465.640,1744.928,177.785,367.385,992.034
|
||||
322,4fe670b5f4,2026-10-31,5969,json_view: decode chains of unicode escapes in a loop (#5969),1390.866,2466.769,6026.817,2328.995,1736.168,475.935,212.530,291.166,2284.708,418.661,1323.436,137.513,1495.099,1736.832,176.566,365.541,963.794
|
||||
323,9c349b1d7c,2026-10-31,5964,Write integers of 17 to 20 digits eight digits at a time in dump() (#5964),1390.500,2469.332,6079.698,2359.276,1718.121,470.647,209.615,289.143,2300.836,419.976,1331.637,138.488,1450.106,1703.483,176.731,365.394,953.483
|
||||
324,3fd3e0fdaa,2026-11-01,5908,json_view: dump and read canada.json-style floats faster (batched float decisions) (#5908),1366.359,2456.409,6058.422,2329.066,1713.347,470.784,209.895,289.318,2294.111,417.490,1319.403,138.100,1435.053,1698.647,176.006,363.191,954.196
|
||||
325,76001c6b4c,2026-11-01,5968,"BSON reader: find C-string terminators 8 bytes at a time, skip array element names (#5968)",1408.222,2488.159,6124.287,2363.039,1759.751,477.558,216.880,294.011,2317.898,420.892,1345.718,138.602,1460.432,1713.978,179.721,370.205,970.525
|
||||
326,1a018577cc,2026-11-01,5970,json_view: accept() checks the text without writing an index (#5970),1427.279,2506.345,6160.916,2368.009,1765.595,480.552,214.060,293.093,2341.368,419.303,1330.990,138.625,1463.731,1724.021,181.150,373.171,964.666
|
||||
327,162eda2574,2026-11-01,5971,json_view: skip the digits of a fraction 16 bytes at a time (SSE2) (#5971),1404.191,2474.144,6049.006,2363.726,1711.013,471.608,211.613,289.736,2290.230,418.673,1322.822,138.556,1441.219,1697.559,178.814,370.881,956.959
|
||||
328,6c3ab966d3,2026-11-01,5975,CBOR reader: read runs of scalar array elements in one loop (#5975),1385.800,2466.923,6050.480,2325.901,1725.552,474.248,210.034,289.350,2296.399,418.689,1327.626,137.722,1440.577,1698.622,178.627,367.797,953.174
|
||||
329,aecbef3949,2026-11-01,5976,Binary readers: swap the bytes of floats with a single byteswap (#5976),1393.659,2479.298,6092.110,2337.421,1718.218,472.539,211.337,289.638,2307.378,417.589,1324.038,137.341,1447.860,1701.387,179.160,369.448,956.324
|
||||
330,edf8d17601,2026-11-01,5980,MessagePack reader: read runs of scalar array elements in one loop (#5980),1422.081,2486.171,6157.302,2360.678,1733.503,477.472,211.189,289.309,2307.724,419.448,1334.857,138.914,1449.345,1721.126,180.127,369.693,967.370
|
||||
331,fb515ddc34,2026-11-01,5981,UBJSON/BJData readers: read optimized arrays of numbers in one loop (#5981),1387.633,2470.528,6067.657,2345.342,1721.303,476.141,212.198,288.466,2292.649,416.597,1324.486,139.598,1441.019,1705.957,179.190,367.903,959.677
|
||||
332,517444b504,2026-11-01,5978,accept() checks strings without copying them (#5978),1385.026,2453.809,5975.744,2322.357,1711.222,475.186,210.256,288.348,2282.444,415.256,1321.012,138.726,1434.772,1698.120,178.106,365.411,976.135
|
||||
333,9742edc294,2026-11-01,5979,"BSON writer: write to_bson(j) in one pass, with sizes written afterwards (#5979)",1418.816,2514.802,6091.854,2380.269,1772.646,474.067,211.598,290.653,2316.886,421.043,1346.324,139.213,1469.659,1754.493,180.269,372.201,982.753
|
||||
334,f022e3c59c,2026-11-01,5982,Binary readers and writers: faster UTF-8 checks of strings (#5982),1399.836,2474.703,6060.781,2341.409,1707.583,468.692,209.824,290.357,2290.034,418.739,1312.448,138.360,1458.779,1707.575,178.911,369.303,968.200
|
||||
335,ddc34f546a,2026-11-01,5974,json_view: exceptions name the path and the bytes of the value (#5974),1394.263,2489.906,6017.599,2345.632,1728.593,473.672,210.364,289.980,2306.608,420.394,1327.301,138.827,1448.846,1707.037,177.406,368.436,978.755
|
||||
336,b2674a4a2f,2026-11-01,5984,BSON reader: check array element names in place in strict mode (#5984),1392.028,2460.989,5975.355,2357.154,1726.291,472.389,209.872,289.219,2301.092,417.632,1309.441,138.779,1438.270,1709.943,177.580,366.368,973.214
|
||||
337,76dbe8f9c9,2026-11-02,6009,"Fix the red CI on develop: Visual Studio 2017 build of the BSON writer, Valgrind timeouts (#6009)",1387.812,2461.244,5975.843,2323.693,1713.572,469.489,209.863,289.058,2291.892,415.935,1306.729,138.322,1447.714,1694.220,177.698,363.994,972.289
|
||||
338,03d408aafa,2026-11-02,6003,JSON_DIAGNOSTIC_POSITIONS: comparing a value-initialized iterator throws instead of crashing (#6003),1385.014,2455.146,5981.995,2380.493,1732.039,466.575,209.272,289.474,2295.226,416.844,1301.454,138.016,1445.840,1703.494,176.691,365.416,967.929
|
||||
339,66e2eeeec0,2026-11-02,6000,Do not construct the base class when destroying a container (#6000),1403.795,2457.426,6001.495,2323.510,1718.268,471.022,210.474,288.385,2308.462,417.187,1313.263,138.770,1437.867,1705.586,179.168,363.523,966.701
|
||||
340,bdc737db6d,2026-11-02,5999,json_view: dump() without StringType::capacity() (#5999),1378.656,2452.954,6020.464,2339.908,1724.630,470.774,211.638,288.939,2303.773,418.311,1312.024,139.010,1446.709,1704.406,177.291,363.859,966.602
|
||||
341,494a74c242,2026-11-02,5996,"insert(): strong guarantee for single elements, basic guarantee for the rest (#5996)",1390.153,2478.991,6032.084,2342.171,1727.040,469.799,213.660,291.104,2307.193,419.623,1329.285,139.000,1461.294,1718.750,178.995,366.898,974.652
|
||||
342,bfe69c73c2,2026-11-02,5992,"json_view: get<T>() of a boolean throws for the exact number types, as basic_json does (#5992)",1387.497,2452.207,6023.042,2335.261,1720.938,471.966,212.162,288.851,2310.949,417.260,1315.155,137.821,1448.762,1710.153,175.990,366.239,970.052
|
||||
343,ff0bdfdef3,2026-11-02,5990,Keep the byte range in exceptions about the root value (#5990),1386.358,2469.197,6037.812,2344.775,1768.382,479.285,214.375,290.939,2329.486,421.838,1332.654,138.666,1455.905,1720.376,178.637,368.500,972.955
|
||||
344,1d69ef9ab4,2026-11-02,5997,"Raise line coverage to 99.9 %: fix the measurement, remove unreachable code, add tests (#5997)",1404.481,2456.447,6166.942,2338.226,1749.981,478.338,211.609,289.387,2304.532,419.095,1321.195,140.055,1460.574,1706.842,179.067,369.688,982.029
|
||||
345,5c4f585ac2,2026-11-02,6004,"Lexer, parser, stream adapter, SAX: remove checks that invariants make dead (#6004)",1386.586,2468.772,6188.662,2373.328,1775.098,483.139,211.476,291.250,2315.874,420.854,1321.718,138.268,1464.254,1709.146,180.316,367.994,965.010
|
||||
346,100f676b3e,2026-11-02,6012,Restore the two commits of #6005 that the stack merge dropped (fixes the build of develop) (#6012),1369.597,2437.356,6122.282,2305.291,1691.485,472.217,208.716,288.666,2291.034,416.120,1300.906,137.896,1439.300,1688.769,176.641,366.389,972.368
|
||||
347,590b622d48,2026-11-02,5991,parse(): propagate std::bad_alloc instead of crashing on a half-constructed member (#5991),1377.480,2425.219,6113.438,2306.435,1716.697,474.315,209.052,288.883,2292.776,417.291,1305.336,137.989,1453.044,1704.638,179.096,368.072,978.198
|
||||
348,6d5581c4e8,2026-11-02,6008,CBOR/MessagePack readers: leave one-element arrays to the general path (#6008),1400.456,2439.163,6140.448,2328.635,1743.039,480.725,212.470,295.268,2348.332,427.202,1340.319,139.121,1489.584,1736.380,184.949,371.567,995.731
|
||||
349,b18b6fc7e6,2026-11-02,6013,Build the parser's syntax error prefix with one concat() (#6013),1370.175,2435.337,6098.834,2320.728,1726.256,472.914,210.817,289.786,2292.841,419.186,1306.593,139.277,1481.709,1714.543,177.065,366.270,971.330
|
||||
350,07876e2292,2026-11-02,6015,json_view: a value that is not found has no bytes in its exception context (#6015),1361.297,2435.980,6080.718,2305.853,1707.733,474.621,210.382,291.568,2337.276,424.783,1329.556,139.590,1450.506,1690.804,178.472,366.370,977.807
|
||||
351,baba5db36f,2026-11-02,6016,"Fix the MSVC and GCC builds of develop (C4127, -Weffc++) (#6016)",1381.280,2440.908,6116.068,2303.611,1713.472,476.121,210.492,290.105,2319.878,420.598,1318.037,139.554,1471.388,1729.097,177.078,369.621,959.145
|
||||
352,candidate,,,develop + open pull requests,1392.967,2469.204,6110.380,2348.760,1730.819,474.089,212.339,290.760,2284.428,420.179,1320.938,137.755,1441.341,1697.486,176.758,364.547,955.117
|
||||
|
@@ -104,8 +104,10 @@ def ribbon(body, x0, y, cw, prefix, label=True):
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- figure 1: parse() vs json_document
|
||||
def layout_tree(b, P):
|
||||
"""panel A: basic_json::parse(), y from 0 to 220"""
|
||||
def layout():
|
||||
W, H, P = 840, 692, "jvl"
|
||||
b = markers(P)
|
||||
# --- panel A: basic_json::parse()
|
||||
b.append(text(16, 26, "basic_json::parse(): a tree, every array, object, and string in its own heap allocation", "nj-jsonview-h"))
|
||||
b.append(rect(16, 98, 60, 34, "nj-jsonview-box"))
|
||||
b.append(text(46, 120, "json", "nj-jsonview-mono", anchor="middle"))
|
||||
@@ -115,7 +117,7 @@ def layout_tree(b, P):
|
||||
rows = [('"port"', "6379", None), ('"price"', "19.9", "double: 19.90 is gone"), ('"tags"', "\u2022", None)]
|
||||
for i, (k, v, note) in enumerate(rows):
|
||||
y = 50 + i * 48
|
||||
b.append(line(192, 115, 226, y + 17, LINE, P))
|
||||
b.append(curve(192, 115, 226, y + 17, LINE, P, bend=0))
|
||||
b.append(rect(228, y, 180, 34, "nj-jsonview-heap"))
|
||||
b.append(text(240, y + 22, k, "nj-jsonview-mono", KEY))
|
||||
b.append(text(396, y + 22, v, "nj-jsonview-mono", NUM if i < 2 else LINE, anchor="end"))
|
||||
@@ -130,9 +132,8 @@ def layout_tree(b, P):
|
||||
b.append('<path class="nj-jsonview-sep" d="M624 %g V%g"/>' % (yt - 17, yt + 17))
|
||||
b.append(text(601, yt + 5, "json", "nj-jsonview-mono", anchor="middle"))
|
||||
b.append(text(647, yt + 5, "json", "nj-jsonview-mono", anchor="middle"))
|
||||
for x1, y1, y2 in ((601, yt - 17, 130), (647, yt + 17, 196)):
|
||||
b.append('<path class="nj-jsonview-arr nj-jsonview-c-%s" d="M%g %g C%g %g %g %g %g %g" marker-end="url(#%s-%s)"/>'
|
||||
% (LINE, x1, y1, x1, y2, x1 + 40, y2, 706, y2, P, LINE))
|
||||
b.append(curve(601, yt - 17, 706, 130, LINE, P, bend=-20))
|
||||
b.append(curve(647, yt + 17, 706, 196, LINE, P, bend=20))
|
||||
b.append(rect(708, 113, 126, 34, "nj-jsonview-heap"))
|
||||
b.append(text(771, 135, "std::string eu", "nj-jsonview-mono nj-jsonview-sm", STR, anchor="middle"))
|
||||
b.append(rect(708, 179, 126, 34, "nj-jsonview-heap"))
|
||||
@@ -140,10 +141,9 @@ def layout_tree(b, P):
|
||||
# legend
|
||||
b.append(rect(16, 186, 18, 14, "nj-jsonview-heap", rx=3))
|
||||
b.append(text(42, 198, "a separate heap allocation", "nj-jsonview-note"))
|
||||
|
||||
|
||||
def layout_index(b, P, y0):
|
||||
"""panel B: json_document::parse(), y from y0 - 16 to y0 + 440"""
|
||||
# --- panel B: json_document::parse()
|
||||
y0 = 252
|
||||
b.append('<path class="nj-jsonview-sep" d="M16 %g H824"/>' % (y0 - 18))
|
||||
b.append(text(16, y0 + 10, "json_document::parse(): the source text stays where it is; one flat index of 16-byte nodes", "nj-jsonview-h"))
|
||||
b.append(text(16, y0 + 38, "source text, 54 bytes (borrowed, or owned by the document)", "nj-jsonview-note"))
|
||||
cw, rx0, ry = 14, 42, y0 + 48
|
||||
@@ -185,25 +185,6 @@ def layout_index(b, P, y0):
|
||||
b.append(curve(vx + 105, vy, n6x, ny + nh, STRUCT, P))
|
||||
b.append(text(30, ny + nh + 50, "integers are converted while parsing and kept in their node;", "nj-jsonview-note"))
|
||||
b.append(text(30, ny + nh + 68, "floats and strings point back into the text", "nj-jsonview-note"))
|
||||
|
||||
|
||||
TREE_DESC = ("The text {\"port\": 6379, \"price\": 19.90, \"tags\": [\"eu\", \"a\\\"b\"]} parsed by basic_json::parse(): "
|
||||
"the root json value points to a std::map whose three nodes are separate heap allocations; the price is stored "
|
||||
"as the double 19.9; the tags array is a std::vector of two json values, each pointing to its own std::string.")
|
||||
INDEX_DESC = ("The same text parsed by json_document::parse(): it keeps the 54 bytes of source text and builds a flat index of "
|
||||
"nine 16-byte nodes in document order: object, key port, unsigned integer 6379 (the converted value is in the "
|
||||
"node), key price, float, key tags, array, string eu, and an escaped string. Keys, the float, and the plain "
|
||||
"string point back into the source text; the escaped string points into the document's buffer of decoded "
|
||||
"strings. A json_view is two pointers: one to the document and one to a node, here the array.")
|
||||
|
||||
|
||||
def layout():
|
||||
# both panels in one figure (features/json_view.md)
|
||||
W, H, P = 840, 692, "jvl"
|
||||
b = markers(P)
|
||||
layout_tree(b, P)
|
||||
b.append('<path class="nj-jsonview-sep" d="M16 234 H824"/>')
|
||||
layout_index(b, P, 252)
|
||||
write("json_view_layout.svg", W, H, "fig-jvl-title",
|
||||
"The same J\u200bSON text parsed by basic_json::parse() and by json_document::parse()",
|
||||
"The text {\"port\": 6379, \"price\": 19.90, \"tags\": [\"eu\", \"a\\\"b\"]}. Top: basic_json::parse() builds a tree: "
|
||||
@@ -214,16 +195,6 @@ def layout():
|
||||
"key tags, array, string eu, and an escaped string. Keys, the float, and the plain string point back into the "
|
||||
"source text; the escaped string points into the document's buffer of decoded strings. A json_view is two "
|
||||
"pointers: one to the document and one to a node, here the array.", b)
|
||||
# each panel on its own (home/blog/how_3_13_0_got_faster.md), with their own marker ids
|
||||
b = markers("jvlt")
|
||||
layout_tree(b, "jvlt")
|
||||
write("json_view_layout_tree.svg", W, 222, "fig-jvlt-title",
|
||||
"A J\u200bSON text parsed by basic_json::parse()", TREE_DESC, b)
|
||||
b = markers("jvli") + ['<g transform="translate(0 -236)">']
|
||||
layout_index(b, "jvli", 252)
|
||||
b.append('</g>')
|
||||
write("json_view_layout_index.svg", W, H - 236, "fig-jvli-title",
|
||||
"The same J\u200bSON text parsed by json_document::parse()", INDEX_DESC, b)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- figure 2: lifetimes
|
||||
|
||||
@@ -1,795 +0,0 @@
|
||||
"""Draws the figures of home/blog/how_3_13_0_got_faster.md as inline SVGs into docs/images/.
|
||||
|
||||
Generated files:
|
||||
|
||||
- perf_blog_overview.svg: speedup of 3.13.0 over 3.12.0 per workload (Google Benchmark suite)
|
||||
- perf_blog_distribution.svg: how many of the suite's benchmarks got how much faster (data/perf_suite.csv)
|
||||
- perf_blog_timeline_<workload>.svg: speedup over 3.12.0 of eight workloads at every develop commit that changed
|
||||
json.hpp or json_view.hpp since 3.12.0, one panel each
|
||||
- perf_blog_swar.svg: the eight-byte string test on one word of input
|
||||
- perf_blog_overlap.svg: writing a short string with two overlapping 16-byte loads and stores
|
||||
- perf_blog_digits.svg: converting eight ASCII digits with three multiplications
|
||||
- perf_blog_cliffs.svg: operations that were quadratic or worse, 3.12.0 against 3.13.0 (log scale)
|
||||
- perf_blog_heldout.svg: validate on the 19 files we didn't tune on, json_document against the fastest library per
|
||||
file (data/perf_heldout_validate.json)
|
||||
- perf_blog_usecases_<platform>.svg: libraries x use cases, time relative to the fastest fully validating library
|
||||
(data/perf_usecases_<platform>.json); perf_blog_tables.py prints the tables of the appendix from the same data
|
||||
|
||||
The numbers are copied from the tables of the post (the timeline from data/perf_timeline.csv, which
|
||||
`tests/benchmarks/history/history.py summarize` writes); the tables stay on the page as the accessible fallback. Update both together.
|
||||
Like the figures of charts.py, the SVGs are not images: the page includes their text with
|
||||
`--8<-- "images/<name>.svg"`, so they follow the colors and fonts of the page (`nj-charts` rules in
|
||||
docs/css/fig-charts.css, `nj-fig` rules in docs/css/brand.css). Run `python3 scripts/figures/perf_blog.py` from
|
||||
docs/mkdocs after changing data or drawing, and commit the generated files.
|
||||
"""
|
||||
import csv
|
||||
import html
|
||||
import json
|
||||
import math
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
OUT = HERE.parents[1] / "docs" / "images"
|
||||
MINUS = "−"
|
||||
TIMES = "×"
|
||||
|
||||
# words the abbreviation extension (includes/glossary.md) would wrap in <abbr> inside the SVG text
|
||||
GLOSSARY = re.findall(r"^\*\[([^\]]+)\]", (HERE.parents[1] / "includes" / "glossary.md").read_text(), re.M)
|
||||
ABBR = re.compile(r"(?<![\w;])(%s)(?!\w)" % "|".join(sorted(map(re.escape, GLOSSARY), key=len, reverse=True)))
|
||||
|
||||
|
||||
def protect(text):
|
||||
return ABBR.sub(lambda m: m.group(1)[0] + "​" + m.group(1)[1:], text)
|
||||
|
||||
|
||||
def esc(s):
|
||||
return html.escape(s, quote=True).replace("&#", "&#")
|
||||
|
||||
|
||||
def esc_md(s):
|
||||
"""esc() for text with _ or *, which the page's Markdown pass would pair across text elements as emphasis"""
|
||||
return esc(s).replace("_", "_").replace("*", "*")
|
||||
|
||||
|
||||
def write(name, W, H, cls, tid, title, desc, body):
|
||||
s = ['<svg class="nj-fig nj-charts %s" viewBox="0 0 %g %g" role="img" aria-labelledby="%s %s-d" '
|
||||
'xmlns="http://www.w3.org/2000/svg">' % (cls, W, H, tid, tid),
|
||||
'<title id="%s">%s</title>' % (tid, esc(title)),
|
||||
'<desc id="%s-d">%s</desc>' % (tid, esc(desc))]
|
||||
s += body
|
||||
s.append('</svg>')
|
||||
text = protect("\n".join(s)) + "\n"
|
||||
assert "\n\n" not in text # a blank line would end the raw HTML block
|
||||
(OUT / name).write_text(text)
|
||||
|
||||
|
||||
def hbar(x0, x1, y, h, r=4):
|
||||
"""Horizontal bar from the baseline x0 to x1, rounded only at the data end."""
|
||||
if abs(x1 - x0) < 0.5:
|
||||
return "M%g %g h0.5 v%g h-0.5 Z" % (x0, y, h)
|
||||
r = min(r, h / 2, abs(x1 - x0))
|
||||
s = 1 if x1 > x0 else -1
|
||||
return ("M%g %g H%g Q%g %g %g %g V%g Q%g %g %g %g H%g Z"
|
||||
% (x0, y, x1 - s * r, x1, y, x1, y + r, y + h - r, x1, y + h, x1 - s * r, y + h, x0))
|
||||
|
||||
|
||||
def fx(v):
|
||||
"""speedup factor for labels: 2 significant digits below 10, integers above"""
|
||||
if v >= 100:
|
||||
return "%d%s" % (round(v), TIMES)
|
||||
if v >= 10:
|
||||
return "%.0f%s" % (v, TIMES)
|
||||
return "%.1f%s" % (v, TIMES) if v >= 1.995 else "%.2f%s" % (v, TIMES)
|
||||
|
||||
|
||||
# ---------- SWAR: one word of a string ----------
|
||||
def swar():
|
||||
text = 'witter",'
|
||||
W, H = 640, 312
|
||||
L, cw, top = 40, 70, 34
|
||||
b = []
|
||||
b.append('<text class="fg-h" x="%g" y="20">eight input bytes, loaded as one 64-bit word (byte 0 is the lowest)</text>' % L)
|
||||
for i, ch in enumerate(text):
|
||||
x = L + i * cw
|
||||
special = ch == '"'
|
||||
b.append('<rect class="fg-cell" x="%g" y="%g" width="%g" height="40" rx="4"/>' % (x, top, cw - 6))
|
||||
if special:
|
||||
b.append('<rect class="nj-charts-c2" fill-opacity=".25" x="%g" y="%g" width="%g" height="40" rx="4"/>' % (x, top, cw - 6))
|
||||
b.append('<text class="fg-code" x="%g" y="%g" text-anchor="middle">%s</text>' % (x + (cw - 6) / 2, top + 26, esc(ch)))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">0x%02X</text>' % (x + (cw - 6) / 2, top + 58, ord(ch)))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">byte %d</text>' % (x + (cw - 6) / 2, top + 74, i))
|
||||
# result row
|
||||
y2 = top + 112
|
||||
b.append('<text class="fg-h" x="%g" y="%g">swar_string_special(): the high bit of each byte that needs handling</text>' % (L, y2 - 14))
|
||||
for i, ch in enumerate(text):
|
||||
x = L + i * cw
|
||||
special = ch == '"'
|
||||
b.append('<rect class="fg-cell" x="%g" y="%g" width="%g" height="34" rx="4"/>' % (x, y2, cw - 6))
|
||||
if special:
|
||||
b.append('<rect class="nj-charts-c2" fill-opacity=".25" x="%g" y="%g" width="%g" height="34" rx="4"/>' % (x, y2, cw - 6))
|
||||
b.append('<text class="fg-code" x="%g" y="%g" text-anchor="middle">%s</text>'
|
||||
% (x + (cw - 6) / 2, y2 + 23, "0x80" if special else "0x00"))
|
||||
# conclusion
|
||||
y3 = y2 + 70
|
||||
b.append('<text class="fg-code" x="%g" y="%g">count_trailing_zeros(0x0080000000000000) = 55</text>' % (L, y3))
|
||||
b.append('<text class="fg-code" x="%g" y="%g">55 / 8 = 6: copy bytes 0 to 5 in one go, then handle the quote</text>' % (L, y3 + 26))
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">No branch per byte: a few subtractions, ANDs and ORs per word,</text>' % (L, y3 + 56))
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">then one count of trailing zeros.</text>' % (L, y3 + 74))
|
||||
write("perf_blog_swar.svg", W, H, "nj-charts--swar", "nj-blog-swar",
|
||||
"Finding the end of a run of ordinary string characters eight bytes at a time",
|
||||
"The eight bytes w, i, t, t, e, r, quote and comma are loaded as one word. The test sets the high bit only in "
|
||||
"byte 6, the quote. Counting trailing zero bits gives 55, divided by eight gives 6: bytes 0 to 5 are copied "
|
||||
"at once, then the quote ends the string.", b)
|
||||
|
||||
|
||||
def span(b, x0, x1, y, cls, label):
|
||||
"""a bracket under the cells from x0 to x1, tinted, with a label to its right or inside"""
|
||||
b.append('<rect class="%s" fill-opacity=".22" x="%g" y="%g" width="%g" height="22" rx="4"/>' % (cls, x0, y, x1 - x0))
|
||||
b.append('<rect class="%s" x="%g" y="%g" width="4" height="22" rx="2"/>' % (cls, x0, y))
|
||||
b.append('<rect class="%s" x="%g" y="%g" width="4" height="22" rx="2"/>' % (cls, x1 - 4, y))
|
||||
b.append('<text class="fg-code" x="%g" y="%g" text-anchor="middle" style="font-size:14px">%s</text>' % ((x0 + x1) / 2, y + 16, label))
|
||||
|
||||
|
||||
# ---------- short strings: two overlapping 16-byte loads ----------
|
||||
def overlap():
|
||||
text = "profile_link_color" # a key of twitter.json, 18 bytes
|
||||
n = len(text)
|
||||
W = 640
|
||||
L, cw, top = 40, 31, 34
|
||||
X = lambda i: L + i * cw
|
||||
b = ['<text class="fg-h" x="%g" y="20">a string of n = %d bytes: too long for one 16-byte vector, too short for a loop</text>' % (L, n)]
|
||||
for i, ch in enumerate(text):
|
||||
both = n - 16 <= i < 16
|
||||
b.append('<rect class="fg-cell" x="%g" y="%g" width="%g" height="36" rx="4"/>' % (X(i), top, cw - 4))
|
||||
if both:
|
||||
b.append('<rect class="nj-charts-c3" fill-opacity=".3" x="%g" y="%g" width="%g" height="36" rx="4"/>' % (X(i), top, cw - 4))
|
||||
b.append('<text class="fg-code" x="%g" y="%g" text-anchor="middle">%s</text>' % (X(i) + (cw - 4) / 2, top + 24, esc_md(ch)))
|
||||
for i in (0, n - 16, 15, n - 1):
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%d</text>' % (X(i) + (cw - 4) / 2, top + 52, i))
|
||||
y = top + 66
|
||||
span(b, X(0), X(15) + cw - 4, y, "nj-charts-c1", "a = load 16 bytes at p")
|
||||
span(b, X(n - 16), X(n - 1) + cw - 4, y + 30, "nj-charts-c2", "b = load 16 bytes at p + n " + MINUS + " 16")
|
||||
y += 82
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">Both loads lie inside the string, and together they cover all of it; bytes %d to 15 are in both.</text>' % (L, y, n - 16))
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">Test a and b for a quote, a backslash, a control character or 0x7F: none, so write</text>' % (L, y + 22))
|
||||
b.append('<text class="fg-code" x="%g" y="%g">store a at d, store b at d + n %s 16</text>' % (L, y + 52, MINUS))
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">The second store writes bytes %d to 15 again, with the same values. For any n from 16 to 32:</text>' % (L, y + 80, n - 16))
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">two loads, one test, two stores, no loop and no branch on the length.</text>' % (L, y + 98))
|
||||
write("perf_blog_overlap.svg", W, y + 112, "nj-charts--swar", "nj-blog-overlap",
|
||||
"Writing an 18-byte string with two overlapping 16-byte loads and stores",
|
||||
"The 18 bytes of profile_link_color. Load a covers bytes 0 to 15, load b covers bytes 2 to 17, so bytes 2 to 15 "
|
||||
"are in both. Neither contains a byte that needs escaping, so a is stored at the destination and b 2 bytes "
|
||||
"later; the second store writes bytes 2 to 15 again with the same values. This works for any length from 16 to "
|
||||
"32 bytes without a loop.", b)
|
||||
|
||||
|
||||
# ---------- eight digits at a time: three multiplications ----------
|
||||
def digits():
|
||||
W = 600
|
||||
L, cw, h = 40, 64, 34
|
||||
X = lambda i: L + i * cw
|
||||
steps = [
|
||||
("eight ASCII digits in one 64-bit word (byte 0 is the lowest)", 1, list("12345678"), True),
|
||||
("& 0x0F0F0F0F0F0F0F0F: one digit value per byte", 1, list("12345678"), False),
|
||||
("× (10 · 2⁸ + 1) >> 8, every second byte kept: two digits per 16 bits", 2, ["12", "34", "56", "78"], False),
|
||||
("× (100 · 2¹⁶ + 1) >> 16, every second lane kept: four digits per 32 bits", 4, ["1234", "5678"], False),
|
||||
("× (10000 · 2³² + 1) >> 32: the value", 8, ["12345678"], False),
|
||||
]
|
||||
b = []
|
||||
y = 20
|
||||
for k, (head, width, cells, ascii_) in enumerate(steps):
|
||||
b.append('<text class="fg-h" x="%g" y="%g">%s</text>' % (L, y, esc(head)))
|
||||
for j, c in enumerate(cells):
|
||||
x = X(j * width)
|
||||
b.append('<rect class="fg-cell" x="%g" y="%g" width="%g" height="%g" rx="4"/>' % (x, y + 10, width * cw - 6, h))
|
||||
if k == len(steps) - 1:
|
||||
b.append('<rect class="nj-charts-c1" fill-opacity=".25" x="%g" y="%g" width="%g" height="%g" rx="4"/>' % (x, y + 10, width * cw - 6, h))
|
||||
b.append('<text class="fg-code" x="%g" y="%g" text-anchor="middle">%s</text>' % (x + (width * cw - 6) / 2, y + 10 + 23, esc(c)))
|
||||
if ascii_:
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">0x%02X</text>' % (x + (width * cw - 6) / 2, y + h + 26, ord(c)))
|
||||
y += h + (58 if ascii_ else 40)
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">Each step combines neighboring lanes, in all lanes of the word at once:</text>' % (L, y - 8))
|
||||
b.append('<text class="fg-note fg-note--l" x="%g" y="%g">three multiplications instead of eight, and no branch.</text>' % (L, y + 10))
|
||||
write("perf_blog_digits.svg", W, y + 22, "nj-charts--swar", "nj-blog-digits",
|
||||
"Converting eight ASCII digits to their value with three multiplications",
|
||||
"The text 12345678 as one word. Masking gives the digit values 1 to 8, one per byte. Multiplying by 10 times 2 to "
|
||||
"the 8 plus 1 and shifting gives 12, 34, 56 and 78 in 16-bit lanes; multiplying by 100 times 2 to the 16 plus 1 "
|
||||
"gives 1234 and 5678 in 32-bit lanes; multiplying by 10000 times 2 to the 32 plus 1 gives 12345678.", b)
|
||||
|
||||
|
||||
# ---------- overview: speedup per workload (Google Benchmark rows, 3.12.0 time / 3.13.0 time) ----------
|
||||
# (group, label, speedup), copied from the table "The short version"
|
||||
OVERVIEW = [
|
||||
("Parsing", "twitter.json", 3.14),
|
||||
("Parsing", "citm_catalog.json", 4.25),
|
||||
("Parsing", "canada.json", 3.35),
|
||||
("Parsing", "canada.json, indented", 6.51),
|
||||
("Parsing", "citm, ordered_json", 6.85),
|
||||
("Parsing", "twitter, std::ifstream", 2.50),
|
||||
("Parsing", "citm, FILE*", 4.74),
|
||||
("Parsing", "citm, accept()", 7.07),
|
||||
("Writing", "dump() twitter", 6.70),
|
||||
("Writing", "dump() canada", 2.98),
|
||||
("Writing", "dump(4) citm", 4.70),
|
||||
("Writing", "to_cbor() twitter", 4.59),
|
||||
("Reading CBOR", "twitter, memory", 3.39),
|
||||
("Reading CBOR", "twitter, FILE*", 6.59),
|
||||
("Values", "diff() canada", 10.46),
|
||||
("Values", "iterate canada", 2.73),
|
||||
("Values", "copy + destroy citm", 1.13),
|
||||
("Values", "== citm", 1.06),
|
||||
]
|
||||
|
||||
|
||||
def overview():
|
||||
W, L, R = 560, 190, 520
|
||||
hi = max(v for _, _, v in OVERVIEW)
|
||||
hi = math.ceil(hi + 0.5)
|
||||
X = lambda v: L + v / hi * (R - L)
|
||||
pitch, bh, top = 24, 15, 8
|
||||
b, desc = [], []
|
||||
y = top
|
||||
group = None
|
||||
rows = []
|
||||
for g, label, v in OVERVIEW:
|
||||
if g != group:
|
||||
if group is not None:
|
||||
y += 10
|
||||
b.append('<text class="nj-charts-panel" x="%g" y="%g">%s</text>' % (8, y + 12, esc(g)))
|
||||
y += 22
|
||||
group = g
|
||||
rows.append((label, v, y))
|
||||
y += pitch
|
||||
axis_y = y + 2
|
||||
for t in range(1, hi + 1):
|
||||
b.append('<line class="nj-charts-grid" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(t), top, X(t), axis_y))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%d%s</text>' % (X(t), axis_y + 16, t, TIMES))
|
||||
for label, v, yy in rows:
|
||||
b.append('<text class="nj-charts-rowlabel nj-charts-tick--r" x="%g" y="%g" text-anchor="end">%s</text>' % (L - 8, yy + bh - 3, esc(label)))
|
||||
b.append('<path class="nj-charts-c1" d="%s"><title>%s: %s</title></path>' % (hbar(X(0), X(v), yy, bh), esc(label), fx(v)))
|
||||
b.append('<text class="nj-charts-val" x="%g" y="%g">%s</text>' % (X(v) + 5, yy + bh - 3, fx(v)))
|
||||
desc.append("%s %s" % (label, fx(v).replace(TIMES, "x")))
|
||||
b.append('<line class="nj-charts-ref" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(1), top, X(1), axis_y))
|
||||
b.append('<line class="nj-charts-zero" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(0), top, X(0), axis_y))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">speedup over 3.12.0 (3.12.0 = 1%s), more is better</text>'
|
||||
% ((L + R) / 2, axis_y + 34, TIMES))
|
||||
write("perf_blog_overview.svg", W, axis_y + 44, "nj-charts--blog", "nj-blog-overview",
|
||||
"Speedup of 3.13.0 over 3.12.0 per workload, Apple M1 Max, Apple clang",
|
||||
"Horizontal bars of the speedup, more is better. " + "; ".join(desc) + ".", b)
|
||||
|
||||
|
||||
# ---------- distribution: how many of the suite's benchmarks got how much faster ----------
|
||||
# bins of the speedup (3.12.0 time / 3.13.0 time) over all rows of data/perf_suite.csv
|
||||
BINS = [(0, 1, "below 1" + TIMES), (1, 1.5, "1 to 1.5" + TIMES), (1.5, 2, "1.5 to 2" + TIMES),
|
||||
(2, 3, "2 to 3" + TIMES), (3, 5, "3 to 5" + TIMES), (5, 10, "5 to 10" + TIMES), (10, 1e9, "10" + TIMES + " or more")]
|
||||
|
||||
|
||||
def distribution():
|
||||
rows = list(csv.DictReader((HERE / "data" / "perf_suite.csv").open()))
|
||||
s = sorted(float(r["speedup"]) for r in rows)
|
||||
n = len(s)
|
||||
counts = [sum(lo <= v < hi for v in s) for lo, hi, _ in BINS]
|
||||
geo = math.exp(sum(math.log(v) for v in s) / n)
|
||||
med = (s[(n - 1) // 2] + s[n // 2]) / 2
|
||||
W, H = 560, 250
|
||||
L, R, T, B = 52, 548, 16, 196
|
||||
hi = 10 * math.ceil(max(counts) / 10 + 0.4)
|
||||
Y = lambda c: B - c / hi * (B - T)
|
||||
slot = (R - L) / len(BINS)
|
||||
b, desc = [], []
|
||||
for t in range(0, hi + 1, 20):
|
||||
b.append('<line class="nj-charts-grid" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (L, Y(t), R, Y(t)))
|
||||
b.append('<text class="nj-charts-tick nj-charts-tick--r" x="%g" y="%g">%d</text>' % (L - 6, Y(t) + 4, t))
|
||||
for k, ((lo, _, label), c) in enumerate(zip(BINS, counts)):
|
||||
x = L + k * slot + 8
|
||||
w = slot - 16
|
||||
cls = "nj-charts-c2" if lo < 1 else "nj-charts-c1"
|
||||
b.append('<rect class="%s" x="%.1f" y="%.1f" width="%.1f" height="%.1f" rx="3"><title>%s: %d</title></rect>'
|
||||
% (cls, x, Y(c), w, B - Y(c), label, c))
|
||||
b.append('<text class="nj-charts-val" x="%.1f" y="%.1f" text-anchor="middle">%d</text>' % (x + w / 2, Y(c) - 5, c))
|
||||
b.append('<text class="nj-charts-tick" x="%.1f" y="%.1f">%s</text>' % (x + w / 2, B + 16, label))
|
||||
desc.append("%s: %d" % (label.replace(TIMES, "x"), c))
|
||||
b.append('<line class="nj-charts-axis" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (L, B, R, B))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">speedup over 3.12.0, more is better</text>' % ((L + R) / 2, H - 10))
|
||||
b.append('<text class="nj-charts-tick" transform="rotate(-90)" x="%g" y="14">number of benchmarks</text>' % (-(T + B) / 2))
|
||||
print("distribution: median %s, geometric mean %s" % (fx(med), fx(geo)))
|
||||
write("perf_blog_distribution.svg", W, H, "nj-charts--blog", "nj-blog-dist",
|
||||
"Speedup of 3.13.0 over 3.12.0 for all %d benchmarks of the suite" % n,
|
||||
"Bars counting the benchmarks per speedup range: " + "; ".join(desc)
|
||||
+ ". Median %s, geometric mean %s." % (fx(med).replace(TIMES, "x"), fx(geo).replace(TIMES, "x")), b)
|
||||
|
||||
|
||||
# ---------- timeline: one panel per workload ----------
|
||||
# (column in perf_timeline.csv, panel title, [(PR, label)]): each labeled step shows the number of the theme that
|
||||
# explains it ("U" for the UTF-8 check of the binary readers that came and went); the appendix maps steps to PRs
|
||||
TIMELINE = [
|
||||
("parse_citm", "parse() citm_catalog.json", [(5234, "4"), (5283, "1"), (5592, "4"), (5809, "4"), (5810, "2"), (5882, "4")]),
|
||||
("parse_canada", "parse() canada.json", [(5234, "4"), (5283, "1"), (5617, "3"), (5738, "3"), (5851, "3"), (5882, "4")]),
|
||||
("accept_twitter", "accept() twitter.json", [(5234, "4"), (5283, "1"), (5592, "4"), (5809, "4"), (5810, "2"), (5853, "2")]),
|
||||
("parse_twitter_ifstream", "parse() twitter.json, std::ifstream", [(5828, "1"), (5884, "1")]),
|
||||
("dump_twitter", "dump() twitter.json", [(5285, "6"), (5738, "2"), (5878, "2"), (5883, "2")]),
|
||||
("dump_canada", "dump() canada.json", [(5285, "6"), (5634, "3")]),
|
||||
("from_cbor_twitter", "from_cbor() twitter", [(5233, "1"), (5501, "4"), (5185, "U"), (5746, "U")]),
|
||||
("to_cbor_twitter", "to_cbor() twitter", [(5328, "4"), (5824, "6"), (5885, "6")]),
|
||||
]
|
||||
MONTHS = [("2025-04", "3.12.0"), ("2026-09", "Sep 2026"), ("2026-10", "Oct")]
|
||||
|
||||
|
||||
def timeline():
|
||||
rows = list(csv.DictReader((HERE / "data" / "perf_timeline.csv").open()))
|
||||
n = len(rows)
|
||||
W, H = 340, 270
|
||||
L, R, T, B = 44, 330, 66, 208
|
||||
for col, title, labels in TIMELINE:
|
||||
vals = [float(r[col]) if r[col] else None for r in rows]
|
||||
base = vals[0]
|
||||
rel = [base / v if v else None for v in vals] # speedup over 3.12.0
|
||||
hi = max(x for x in rel if x)
|
||||
top = 2 ** math.ceil(math.log2(hi * 1.3))
|
||||
Y = lambda s: B - math.log2(s) / math.log2(top) * (B - T)
|
||||
X = lambda i: L + i / (n - 1) * (R - L)
|
||||
b = ['<text class="nj-charts-panel" x="%g" y="18">%s</text>' % (8, esc(title))]
|
||||
t = 1
|
||||
while t <= top:
|
||||
b.append('<line class="nj-charts-grid" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (L, Y(t), R, Y(t)))
|
||||
b.append('<text class="nj-charts-tick nj-charts-tick--r" x="%g" y="%g">%d%s</text>' % (L - 6, Y(t) + 4, t, TIMES))
|
||||
t *= 2
|
||||
# month ticks: first commit of the month
|
||||
seen = set()
|
||||
for i, r in enumerate(rows):
|
||||
m = r["date"][:7]
|
||||
for key, name in MONTHS:
|
||||
if m == key and key not in seen:
|
||||
seen.add(key)
|
||||
b.append('<line class="nj-charts-axis" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(i), B, X(i), B + 4))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%s</text>' % (X(i), B + 17, name))
|
||||
# a step line: each commit's value holds until the next commit
|
||||
pts, prev = [], None
|
||||
for i, s in enumerate(rel):
|
||||
if s is None:
|
||||
continue
|
||||
if prev is not None:
|
||||
pts.append("%.1f,%.1f" % (X(i), Y(prev)))
|
||||
pts.append("%.1f,%.1f" % (X(i), Y(s)))
|
||||
prev = s
|
||||
b.append('<polyline class="nj-charts-json" points="%s"/>' % " ".join(pts))
|
||||
# labels for named steps: a dot at the commit and its PR number above it; PRs a few commits apart share a
|
||||
# label, and a label that would overlap one already placed moves up
|
||||
groups = []
|
||||
for pr, lab in labels:
|
||||
i = next(k for k, r in enumerate(rows) if r["pr"] == str(pr))
|
||||
if groups and X(i) - X(groups[-1][-1][1]) < 6:
|
||||
groups[-1].append((pr, i, lab))
|
||||
else:
|
||||
groups.append([(pr, i, lab)])
|
||||
# labels in two rows above the plot, each with a guide down to its dot
|
||||
placed = []
|
||||
for g in groups:
|
||||
i = g[-1][1]
|
||||
x, y = X(i), Y(rel[i])
|
||||
for pr, k, lab in g:
|
||||
b.append('<circle class="nj-charts-json-dot" cx="%.1f" cy="%.1f" r="3.5"><title>#%s: %s</title></circle>'
|
||||
% (X(k), Y(rel[k]), pr, fx(rel[k])))
|
||||
marks = list(dict.fromkeys(lab for _, _, lab in g))
|
||||
w = 18 * len(marks) - 3
|
||||
tx = min(max(x, L + w / 2), R - w / 2)
|
||||
row = 0
|
||||
while any(r == row and abs(tx - px) < (w + pw) / 2 + 4 for px, r, pw in placed):
|
||||
row += 1
|
||||
placed.append((tx, row, w))
|
||||
ty = 46 - 18 * row # the center of the badges
|
||||
b.append('<line class="nj-charts-grid" stroke-dasharray="2 2" x1="%.1f" y1="%.1f" x2="%.1f" y2="%.1f"/>' % (x, ty + 8, x, y - 5))
|
||||
for k, mark in enumerate(marks):
|
||||
cx = tx - w / 2 + 7.5 + 18 * k
|
||||
b.append('<circle class="nj-theme-dot%s" cx="%.1f" cy="%.1f" r="7.5"/>' % ("" if mark.isdigit() else " nj-theme-dot--other", cx, ty))
|
||||
b.append('<text class="nj-theme-num" x="%.1f" y="%.1f" text-anchor="middle">%s</text>' % (cx, ty + 4, mark))
|
||||
b.append('<line class="nj-charts-axis" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (L, B, R, B))
|
||||
b.append('<text class="nj-charts-note" x="%g" y="%g">speedup over 3.12.0 (log scale), more is better</text>' % (8, H - 8))
|
||||
final = rel[-1]
|
||||
desc = ("%s: speedup over 3.12.0 at each of %d commits, ending at %s. Labeled steps, by theme: %s."
|
||||
% (title, n, fx(final).replace(TIMES, "x"), ", ".join(lab for _, lab in labels)))
|
||||
write("perf_blog_timeline_%s.svg" % col, W, H, "nj-charts--timeline", "nj-blog-tl-" + col,
|
||||
"%s: speedup over 3.12.0 by commit" % title, desc, b)
|
||||
|
||||
|
||||
# ---------- cliffs: 3.12.0 and 3.13.0 times on a log axis ----------
|
||||
# (operation, 3.12.0 ms, 3.13.0 ms), copied from the table in "Fix the algorithm first"
|
||||
CLIFFS = [
|
||||
("diff() 64k numbers vs []", 4237, 10.8),
|
||||
("diff() 20k objects vs half", 122, 4.13),
|
||||
("parse() callback, 32k objects", 1398, 12.1),
|
||||
("operator< nested 24 deep", 64.4, 0.002),
|
||||
("operator< citm, 10x", 284, 3.94),
|
||||
("flatten() citm, ordered_json", 271, 1.45),
|
||||
("to_bson() 200 deep, 100x", 20.3, 0.352),
|
||||
("push_back() 100k, diagnostics", 1589, 5.32),
|
||||
("at(i) 10k, diagnostics", 45.9, 0.088),
|
||||
]
|
||||
|
||||
|
||||
def cliffs():
|
||||
W, L, R = 600, 250, 585
|
||||
lo, hi = -3, 4 # 1 µs .. 10 s, in log10 ms
|
||||
X = lambda ms: L + (math.log10(ms) - lo) / (hi - lo) * (R - L)
|
||||
top, pitch = 40, 34
|
||||
b, desc = [], []
|
||||
axis_y = top + pitch * len(CLIFFS) - 10
|
||||
for e in range(lo, hi + 1):
|
||||
b.append('<line class="nj-charts-grid" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(10 ** e), top - 10, X(10 ** e), axis_y))
|
||||
lab = {-3: "1 µs", -2: "10 µs", -1: "0.1 ms", 0: "1 ms", 1: "10 ms", 2: "0.1 s", 3: "1 s", 4: "10 s"}[e]
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%s</text>' % (X(10 ** e), axis_y + 16, lab))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">runtime (log scale), less is better</text>' % ((L + R) / 2, axis_y + 34))
|
||||
b.append('<defs><marker id="nj-blog-cliffs-head" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="5" markerHeight="5" '
|
||||
'orient="auto"><path class="nj-charts-head" d="M0 0 L10 5 L0 10 z"/></marker></defs>')
|
||||
b.append('<circle class="nj-charts-ojson-dot" cx="%g" cy="14" r="5"/><text class="nj-charts-leg" x="%g" y="18.5">3.12.0</text>' % (L, L + 10))
|
||||
b.append('<circle class="nj-charts-json-dot" cx="%g" cy="14" r="5"/><text class="nj-charts-leg" x="%g" y="18.5">3.13.0</text>' % (L + 80, L + 90))
|
||||
for i, (op, old, new) in enumerate(CLIFFS):
|
||||
y = top + i * pitch + 8
|
||||
b.append('<text class="nj-charts-rowlabel" x="%g" y="%g" text-anchor="end">%s</text>' % (L - 10, y + 4, esc(op)))
|
||||
# an arrow from the old time to the new one, ending just before the new dot
|
||||
b.append('<line class="nj-charts-axis" x1="%g" y1="%g" x2="%g" y2="%g" marker-end="url(#nj-blog-cliffs-head)"/>'
|
||||
% (X(old) - 6, y, X(new) + 7, y))
|
||||
b.append('<circle class="nj-charts-ojson-dot" cx="%g" cy="%g" r="5"><title>%s, 3.12.0: %g ms</title></circle>' % (X(old), y, esc(op), old))
|
||||
b.append('<circle class="nj-charts-json-dot" cx="%g" cy="%g" r="5"><title>%s, 3.13.0: %g ms</title></circle>' % (X(new), y, esc(op), new))
|
||||
b.append('<text class="nj-charts-factor" x="%g" y="%g">%s</text>' % ((X(old) + X(new)) / 2, y - 7, fx(old / new)))
|
||||
desc.append("%s: %g ms to %g ms" % (op, old, new))
|
||||
write("perf_blog_cliffs.svg", W, axis_y + 44, "nj-charts--blog", "nj-blog-cliffs",
|
||||
"Operations that grew quadratically or worse: time with 3.12.0 and 3.13.0, log scale",
|
||||
"Dot plot on a logarithmic time axis, less is better; an arrow leads from each 3.12.0 time to the 3.13.0 time. " + "; ".join(desc) + ".", b)
|
||||
|
||||
|
||||
# ---------- validating the files we didn't tune on, file by file ----------
|
||||
# data/perf_heldout_validate.json: per platform, file and library the fastest fully validating way of the validate
|
||||
# use case on the 19 other files of simdjson's jsonexamples (reused parsers not chosen), extracted from
|
||||
# summarize.py --json of the held-out run
|
||||
HELDOUT = [("mac", "Apple M1 Max", "nj-charts-json-dot"), ("x86-gcc", "x86-64, GCC 16.2", "nj-charts-ojson-dot")]
|
||||
|
||||
|
||||
def heldout():
|
||||
data = json.load((HERE / "data" / "perf_heldout_validate.json").open())
|
||||
files = sorted(data["mac"])
|
||||
rel, winner = {}, {}
|
||||
for plat, _, _ in HELDOUT:
|
||||
for f in files:
|
||||
libs = data[plat][f]
|
||||
# the fastest other library: below 1 json_document is the fastest, and the distance shows by how much
|
||||
best = min((l for l in libs if l != "nlohmann json_document"), key=lambda l: libs[l]["us"])
|
||||
rel[plat, f] = libs["nlohmann json_document"]["us"] / libs[best]["us"]
|
||||
winner[plat, f] = UC_LIBS.get(best, best)
|
||||
files.sort(key=lambda f: (rel["x86-gcc", f], rel["mac", f]))
|
||||
W, L, R = 620, 262, 486
|
||||
lo, hi = 0.4, 1.15
|
||||
X = lambda r: L + (r - lo) / (hi - lo) * (R - L)
|
||||
top, pitch = 58, 20
|
||||
axis_y = top + pitch * len(files)
|
||||
b, desc = [], []
|
||||
for t in (0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1):
|
||||
b.append('<line class="nj-charts-grid" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(t), top - 8, X(t), axis_y))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%.1f%s</text>' % (X(t), axis_y + 16, t, TIMES))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">json_document’s time / the fastest other library’s, less is better</text>' % ((L + R) / 2, axis_y + 34))
|
||||
x = 8
|
||||
for plat, name, cls in HELDOUT:
|
||||
b.append('<circle class="%s" cx="%g" cy="14" r="5"/><text class="nj-charts-leg" x="%g" y="18.5">%s</text>' % (cls, x + 5, x + 15, esc_md(name)))
|
||||
x += 30 + 7.6 * len(name)
|
||||
b.append('<text class="nj-charts-tick nj-charts-tick--l" x="%g" y="%g">next on x86-64</text>' % (R + 14, top - 10))
|
||||
for i, f in enumerate(files):
|
||||
y = top + i * pitch + 6
|
||||
b.append('<text class="nj-charts-rowlabel nj-charts-code" x="%g" y="%g" text-anchor="end">%s</text>' % (L - 10, y + 4, esc_md(f)))
|
||||
for k, (plat, name, cls) in enumerate(HELDOUT):
|
||||
r = rel[plat, f]
|
||||
b.append('<circle class="%s" cx="%.1f" cy="%g" r="4.5"><title>%s, %s: %.2f%s the time of %s</title></circle>'
|
||||
% (cls, X(max(lo, min(r, hi))), y - 3.5 + 7 * k, esc_md(f), esc_md(name), r, TIMES, esc_md(winner[plat, f])))
|
||||
w = winner["x86-gcc", f]
|
||||
b.append('<text class="nj-charts-tick nj-charts-tick--l%s" x="%g" y="%g">%s</text>'
|
||||
% (" nj-charts-best" if rel["x86-gcc", f] > 1.0005 else "", R + 14, y + 4, esc_md(w)))
|
||||
desc.append("%s: Mac %.2f, x86-64 %.2f (%s)" % (f, rel["mac", f], rel["x86-gcc", f], w))
|
||||
b.append('<line class="nj-charts-ref" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(1), top - 8, X(1), axis_y))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">as fast as the next</text>' % (X(1), top - 14))
|
||||
wins = {p: sum(rel[p, f] < 1 for f in files) for p, _, _ in HELDOUT}
|
||||
print("heldout: json_document fastest on %s" % wins)
|
||||
write("perf_blog_heldout.svg", W, axis_y + 44, "nj-charts--blog", "nj-blog-heldout",
|
||||
"Validating 19 files 3.13.0 was not tuned on: json_document's time relative to the fastest other library per file",
|
||||
"Dot plot per file, less is better; below 1.0 json_document is the fastest fully validating library. "
|
||||
+ "; ".join(desc) + ".", b)
|
||||
|
||||
|
||||
# ---------- the price: compile time of two programs against 3.12.0 ----------
|
||||
# CPU time of the compiler in ms, median of 5 interleaved rounds, C++20, M1 Max (the post's appendix G)
|
||||
# (3.12.0, 3.13.0, 3.13.0 with a precompiled header, 3.13.0 as a module)
|
||||
PRICE = [
|
||||
("Apple clang 21, -O0 (debug)", [("count_numbers", 955.0, 1320.5, 688.5, 917.5), ("server_config", 1113.2, 1496.4, 862.6, 1135.5)]),
|
||||
("Apple clang 21, -O2", [("count_numbers", 1393.2, 2081.0, 1458.4, 1684.6), ("server_config", 1753.5, 2545.6, 1925.3, 2168.6)]),
|
||||
("GCC 16, -O0 (debug)", [("count_numbers", 1569.4, 2548.4, 1725.0, 1699.8), ("server_config", 2025.4, 2985.1, 2301.6, 2325.8)]),
|
||||
("GCC 16, -O2", [("count_numbers", 2336.0, 3701.5, 2986.8, 2913.4), ("server_config", 3121.5, 4714.2, 4006.2, 4054.9)]),
|
||||
]
|
||||
PRICE_SERIES = [("3.13.0", "nj-charts-c2"), ("3.13.0, precompiled header", "nj-charts-c1"), ("3.13.0, module", "nj-charts-c3")]
|
||||
|
||||
|
||||
def price():
|
||||
W, L, R = 600, 150, 560
|
||||
lo, hi = -50, 70
|
||||
X = lambda pct: L + (pct - lo) / (hi - lo) * (R - L)
|
||||
pct = lambda new, old: round((new / old - 1) * 100)
|
||||
lab = lambda p: (MINUS + "%d %%" % -p) if p < 0 else "+%d %%" % p
|
||||
bh, pitch, gap = 11, 14, 10
|
||||
b, desc = [], []
|
||||
# the key above the plot
|
||||
x = 8
|
||||
for name, cls in PRICE_SERIES:
|
||||
b.append('<rect class="%s" x="%g" y="6" width="12" height="12" rx="3"/>' % (cls, x))
|
||||
b.append('<text class="nj-charts-leg" x="%g" y="16.5">%s</text>' % (x + 18, esc(name)))
|
||||
x += 18 + 8.2 * len(name) + 22
|
||||
top = 54
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">as fast as 3.12.0</text>' % (X(0), top - 8))
|
||||
y = top
|
||||
for build, progs in PRICE:
|
||||
b.append('<text class="nj-charts-panel" x="8" y="%g">%s</text>' % (y + 14, esc(build)))
|
||||
y += 24
|
||||
y0, at = y, len(b)
|
||||
for prog, old, *new in progs:
|
||||
b.append('<text class="nj-charts-rowlabel nj-charts-code" x="%g" y="%g" text-anchor="end">%s</text>'
|
||||
% (L - 8, y + 1.5 * pitch + 2, prog))
|
||||
for (name, cls), t in zip(PRICE_SERIES, new):
|
||||
p = pct(t, old)
|
||||
b.append('<path class="%s" d="%s"><title>%s, %s, %s: %s ms against %s ms with 3.12.0 (%s)</title></path>'
|
||||
% (cls, hbar(X(0), X(p), y, bh), prog, esc(build), esc(name), format(round(t), ","), format(round(old), ","), lab(p)))
|
||||
if p < 0:
|
||||
b.append('<text class="nj-charts-val" x="%g" y="%g" text-anchor="end">%s</text>' % (X(p) - 5, y + bh - 1.5, lab(p)))
|
||||
else:
|
||||
b.append('<text class="nj-charts-val" x="%g" y="%g">%s</text>' % (X(p) + 5, y + bh - 1.5, lab(p)))
|
||||
desc.append("%s, %s, %s: %s" % (build, prog, name, lab(p).replace(MINUS, "-")))
|
||||
y += pitch
|
||||
y += gap - (pitch - bh)
|
||||
# the grid behind this panel's bars only, so that it doesn't cross the panel titles
|
||||
b[at:at] = ['<line class="nj-charts-grid" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(t), y0 - 4, X(t), y - gap + 4)
|
||||
for t in range(lo + 10, hi + 1, 20) if t]
|
||||
y += 8
|
||||
axis_y = y
|
||||
b.append('<line class="nj-charts-ref" x1="%g" y1="%g" x2="%g" y2="%g"/>' % (X(0), top - 2, X(0), axis_y))
|
||||
for t in range(lo + 10, hi + 1, 20):
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%s</text>' % (X(t), axis_y + 16, "0" if t == 0 else lab(t)))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">compile time compared with 3.12.0, less is better</text>' % ((L + R) / 2, axis_y + 34))
|
||||
write("perf_blog_price.svg", W, axis_y + 44, "nj-charts--blog", "nj-blog-price",
|
||||
"Compile time of two programs with 3.13.0, alone, with a precompiled header and as a module, compared with 3.12.0",
|
||||
"Horizontal bars of the change in compile time against 3.12.0, less is better. " + "; ".join(desc) + ".", b)
|
||||
|
||||
|
||||
# ---------- use cases: libraries x use cases, relative time ----------
|
||||
# data/perf_usecases_<platform>.json is written by tests/benchmarks/json_view/others/summarize.py --json
|
||||
UC_FILES = ["twitter", "citm_catalog", "canada", "jeopardy"]
|
||||
USE_CASES = [("validate", "validate"), ("sum", "sum"), ("select", "select"),
|
||||
("edit", "edit"), ("minify", "minify"), ("write", "write")]
|
||||
UC_LIBS = { # library in the JSON -> row label
|
||||
"nlohmann json_document": "nlohmann/json json_document", "nlohmann json": "nlohmann/json json",
|
||||
"yyjson": "yyjson", "simdjson": "simdjson", "sonic-cpp": "sonic-cpp", "Glaze": "Glaze", "Boost.JSON": "Boost.JSON",
|
||||
"RapidJSON": "RapidJSON", "sonic-rs": "sonic-rs (Rust)", "simd-json": "simd-json (Rust)", "serde_json": "serde_json (Rust)",
|
||||
}
|
||||
UC_PLATFORMS = [("mac", "Use cases: time of each library relative to the fastest, Apple M1 Max"),
|
||||
("x86-gcc", "Use cases: time of each library relative to the fastest, x86-64 with GCC 16.2"),
|
||||
("x86-gcc13", "Use cases: time of each library relative to the fastest, x86-64 with GCC 13"),
|
||||
("x86-clang", "Use cases: time of each library relative to the fastest, x86-64 with Clang 23")]
|
||||
LEVEL_MARK = {"no UTF-8": "U", "partial": "P", "full": ""}
|
||||
# why a cell is empty (the tooltips of the n/a cells)
|
||||
NA = {("simdjson", "edit"): "simdjson's documents are read-only: it has no API to change a value and write the result"}
|
||||
|
||||
|
||||
def geomean(xs):
|
||||
return math.exp(sum(math.log(x) for x in xs) / len(xs))
|
||||
|
||||
|
||||
WRITING = ("edit", "minify", "write") # the use cases that write numbers
|
||||
NUMBER_TEXT = ("source numbers", "raw numbers") # variants that write each number by copying its text
|
||||
|
||||
|
||||
def normalize_usecases(data):
|
||||
"""Chooses each library's best variants again with the rules of the post: variants that reuse a parser or document
|
||||
across calls are measured but not chosen. Variants that write each number by copying its text instead of formatting
|
||||
it (json_document's number_format::source, yyjson's and RapidJSON's raw numbers in edit, minify and write) are not
|
||||
chosen as the fully validating way, but as a way that does less, marked "N" like "U" and "P". Skipping the number
|
||||
conversion while reading is allowed. Each pick has a "mark": "", or the letters of what it skips"""
|
||||
data = json.loads(json.dumps(data))
|
||||
rank = {"full": 0, "n/a": 0, "no UTF-8": 1, "partial": 2}
|
||||
for uc, files in data.items():
|
||||
numtext = lambda k: uc in WRITING and any(w in k for w in NUMBER_TEXT)
|
||||
for cell in files.values():
|
||||
for e in cell.values():
|
||||
vs = [(v["us"], k, v["level"]) for k, v in e["variants"].items() if "reused" not in k]
|
||||
full = [v for v in vs if rank[v[2]] == 0 and not numtext(v[1])]
|
||||
pick = lambda v: {"us": v[0], "variant": v[1], "level": "full" if rank[v[2]] == 0 else v[2],
|
||||
"mark": " ".join(m for m in (LEVEL_MARK.get(v[2], ""), "N" if numtext(v[1]) else "") if m)}
|
||||
e["best"] = pick(min(full)) if full else None
|
||||
e["best_any"] = pick(min(vs))
|
||||
return data
|
||||
|
||||
|
||||
FILE_NAMES = {"twitter": "twitter.json", "citm_catalog": "citm_catalog.json", "canada": "canada.json",
|
||||
"jeopardy": "jeopardy.json"}
|
||||
# what a variant that checks less skips, worded as the trade it is (the tooltips of the heatmaps)
|
||||
CHECKS_LESS = [
|
||||
("simdjson", "On-Demand", "reads lazily: On-Demand reads only what you ask for and steps over the rest by matching brackets"),
|
||||
("simdjson", "minify", "simdjson::minify() only removes whitespace, without parsing the values"),
|
||||
("Glaze", "lazy_json", "reads lazily: lazy_json reads only what you ask for and steps over the rest"),
|
||||
("Glaze", "minify_json", "minify_json only removes whitespace, without parsing the values"),
|
||||
("Glaze", "generic", "accepts trailing garbage after the value: Glaze's default (validate_trailing_whitespace checks it)"),
|
||||
("Glaze", "structs", "reads into structs and steps over fields it doesn't know without checking them "
|
||||
"(validate_skipped checks them too)"),
|
||||
("RapidJSON", "", "trusts UTF-8: RapidJSON's default (kParseValidateEncodingFlag checks it)"),
|
||||
("sonic-cpp", "", "trusts UTF-8: sonic-cpp 1.0.2 doesn't check it"),
|
||||
("serde_json", "", "trusts UTF-8 in the strings it skips (from_slice); strings it reads are checked"),
|
||||
]
|
||||
# what a variant that copies number text does (the "N" half of edit, minify and write)
|
||||
NUMBER_TEXT_TIPS = {
|
||||
"nlohmann json_document": "copies each number's text instead of formatting it (number_format::source)",
|
||||
"yyjson": "copies each number's text instead of formatting it (YYJSON_READ_NUMBER_AS_RAW)",
|
||||
"RapidJSON": "copies each number's text instead of formatting it (kParseNumbersAsStringsFlag)",
|
||||
}
|
||||
|
||||
|
||||
def checks_less(lib, variant):
|
||||
for l, v, text in CHECKS_LESS:
|
||||
if l == lib and v in variant:
|
||||
return text
|
||||
return "checks less"
|
||||
|
||||
|
||||
def usecase_table(data):
|
||||
"""{library: {use case: cell}}: per library the geometric mean over UC_FILES of its fastest fully validating time
|
||||
("full") and of its fastest time at any level ("alt", only if it is at least 3 % faster), each divided by the best
|
||||
such fully validating mean in the use case, so that every file counts equally and the fastest library is 1.00"""
|
||||
out = {}
|
||||
data = normalize_usecases(data)
|
||||
for uc, _ in USE_CASES:
|
||||
files = data.get(uc, {})
|
||||
if not files:
|
||||
continue
|
||||
cells = {}
|
||||
for lib in UC_LIBS:
|
||||
es = [files.get(f, {}).get(lib) for f in UC_FILES]
|
||||
if not all(es):
|
||||
continue
|
||||
full = [e["best"] for e in es]
|
||||
alt = [e["best_any"] for e in es]
|
||||
cells[lib] = {"full": geomean([b["us"] for b in full]) if all(full) else None, "alt": geomean([a["us"] for a in alt]),
|
||||
"files": [(f, b, a) for f, b, a in zip(UC_FILES, full, alt)]}
|
||||
ref = min(c["full"] for c in cells.values() if c["full"])
|
||||
for lib, c in cells.items():
|
||||
full = c["full"] / ref if c["full"] else None
|
||||
alt = c["alt"] / ref
|
||||
if full is not None and alt > full * 0.97:
|
||||
alt = None
|
||||
levels = {a["level"] for _, _, a in c["files"]} if alt is not None else set()
|
||||
level = "partial" if "partial" in levels else "no UTF-8" if "no UTF-8" in levels else "full"
|
||||
numtext = alt is not None and any("N" in a["mark"].split() for _, _, a in c["files"])
|
||||
marks = " ".join(m for m in (LEVEL_MARK[level], "N" if numtext else "") if m)
|
||||
out.setdefault(lib, {})[uc] = {"full": full, "alt": alt, "level": level, "marks": marks, "files": c["files"]}
|
||||
return out
|
||||
|
||||
|
||||
# cell colors: green for the fastest, gray around twice the time, red for the slowest; the upper bounds of the steps
|
||||
HEAT_STEPS = [1.15, 1.5, 2.5, 5, float("inf")]
|
||||
HEAT_LABELS = ["below 1.15", "1.15 to 1.5", "1.5 to 2.5", "2.5 to 5", "5 and more"]
|
||||
|
||||
|
||||
def heat(r):
|
||||
return next(i for i, b in enumerate(HEAT_STEPS) if r < b)
|
||||
|
||||
|
||||
def fr(r):
|
||||
return "%.2f" % r if r < 9.995 else "%.1f" % r if r < 99.95 else "%.0f" % r
|
||||
|
||||
|
||||
def fus(us):
|
||||
return "{:,.0f} µs".format(us) if us >= 100 else "%.1f µs" % us
|
||||
|
||||
|
||||
def tip(lib, uc_label, c, half):
|
||||
"""the tooltip of a cell: lines separated by newlines ( in the attribute), the first one the heading"""
|
||||
if half == "full":
|
||||
lines = ["%s · %s" % (UC_LIBS[lib], uc_label),
|
||||
"%s× the time of the fastest library (fully validating)" % fr(c["full"])]
|
||||
picks = [(f, b) for f, b, _ in c["files"]]
|
||||
else:
|
||||
lines = ["%s · %s, checking less" % (UC_LIBS[lib], uc_label),
|
||||
"%s× the time of the fastest fully validating library" % fr(c["alt"])]
|
||||
picks = [(f, a) for f, _, a in c["files"]]
|
||||
ways = sorted({e["variant"] for _, e in picks})
|
||||
if len(ways) == 1:
|
||||
lines.append("way: %s" % ways[0])
|
||||
for f, e in picks:
|
||||
lines.append("%s: %s%s%s" % (FILE_NAMES[f], fus(e["us"]), "" if len(ways) == 1 else " · " + e["variant"],
|
||||
" (validates fully)" if half == "alt" and e["level"] == "full" else ""))
|
||||
if half == "alt":
|
||||
seen = []
|
||||
for _, e in picks:
|
||||
ts = ([checks_less(lib, e["variant"])] if e["level"] != "full" else []) + \
|
||||
([NUMBER_TEXT_TIPS.get(lib, "copies each number's text instead of formatting it")] if "N" in e["mark"].split() else [])
|
||||
for t in ts:
|
||||
if t not in seen:
|
||||
seen.append(t)
|
||||
lines += seen
|
||||
if any("(copy)" in e["variant"] for _, e in picks):
|
||||
lines.append("(copy): parses in place, on a copy of the input that is part of the time")
|
||||
return " ".join(lines)
|
||||
|
||||
|
||||
def heatmap(platform, title):
|
||||
data = json.load((HERE / "data" / ("perf_usecases_%s.json" % platform)).open())
|
||||
t = usecase_table(data)
|
||||
libs = [l for l in UC_LIBS if l in t]
|
||||
score = lambda l: geomean([v["full"] or v["alt"] for v in t[l].values()]) # the mean of the row as shown
|
||||
libs.sort(key=score)
|
||||
W, L, cw, ch, top = 784, 224, 92, 36, 44
|
||||
b, desc = [], []
|
||||
for j, (uc, label) in enumerate(USE_CASES):
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">%s</text>' % (L + j * cw + cw / 2, top - 10, esc(label)))
|
||||
for i, lib in enumerate(libs):
|
||||
y = top + i * ch
|
||||
cls = "nj-charts-name-json" if lib.startswith("nlohmann") else ""
|
||||
b.append('<text class="nj-charts-rowlabel %s" x="%g" y="%g" text-anchor="end">%s</text>' % (cls, L - 8, y + ch / 2 + 4, esc(UC_LIBS[lib])))
|
||||
for j, (uc, label) in enumerate(USE_CASES):
|
||||
x = L + j * cw
|
||||
c = t[lib].get(uc)
|
||||
if c is None:
|
||||
b.append('<g class="nj-heat-cell" tabindex="0" data-tip="%s">' % esc("%s · %s %s" % (UC_LIBS[lib], label, NA.get((lib, uc), "the library has no API for this use case"))))
|
||||
b.append('<rect class="nj-heat-na" x="%g" y="%g" width="%g" height="%g" rx="3"/>' % (x + 1, y + 1, cw - 2, ch - 2))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">n/a</text>' % (x + cw / 2, y + ch / 2 + 4))
|
||||
b.append('</g>')
|
||||
desc.append("%s %s: n/a" % (UC_LIBS[lib], label))
|
||||
continue
|
||||
halves = []
|
||||
if c["full"] is not None:
|
||||
halves.append(("full", c["full"]))
|
||||
if c["alt"] is not None:
|
||||
halves.append(("alt", c["alt"]))
|
||||
hw = (cw - 2) / len(halves)
|
||||
for k, (half, r) in enumerate(halves):
|
||||
hx = x + 1 + k * hw
|
||||
gap = 1 if len(halves) == 2 else 0
|
||||
b.append('<g class="nj-heat-cell" tabindex="0" data-tip="%s">' % esc(tip(lib, label, c, half)))
|
||||
b.append('<rect class="nj-heat-%d" x="%g" y="%g" width="%g" height="%g" rx="3"/>'
|
||||
% (heat(r), hx + (gap if k else 0), y + 1, hw - gap, ch - 2))
|
||||
cx = hx + hw / 2
|
||||
if half == "alt":
|
||||
b.append('<text class="nj-charts-cell" x="%g" y="%g" text-anchor="middle">%s</text>' % (cx, y + 16, fr(r)))
|
||||
b.append('<text class="nj-charts-cell nj-charts-cell--small" x="%g" y="%g" text-anchor="middle">%s</text>'
|
||||
% (cx, y + 29, c["marks"]))
|
||||
else:
|
||||
b.append('<text class="nj-charts-cell" x="%g" y="%g" text-anchor="middle">%s</text>' % (cx, y + ch / 2 + 4, fr(r)))
|
||||
b.append('</g>')
|
||||
if c["full"] is None: # no fully validating way: the left half stays empty
|
||||
pass
|
||||
desc.append("%s %s: %s%s" % (UC_LIBS[lib], label, fr(c["full"]) if c["full"] else "no fully validating way",
|
||||
(" (%s doing less, %s)" % (fr(c["alt"]), c["marks"])) if c["alt"] else ""))
|
||||
# the key, set apart from the grid and narrower than its columns, so that it doesn't read as a row of it
|
||||
yb = top + len(libs) * ch + 28
|
||||
b.append('<text class="nj-charts-tick nj-charts-tick--l" x="8" y="%g">time relative to the fastest fully validating library, less is better</text>' % (yb + 4))
|
||||
kw, ky = 76, yb + 14
|
||||
for i, lab in enumerate(HEAT_LABELS):
|
||||
# each swatch in its own group, so that the ink rule for the strong steps (a sibling selector) stays inside it
|
||||
b.append('<g><rect class="nj-heat-%d" x="%g" y="%g" width="%g" height="20" rx="3"/>' % (i, 8 + i * (kw + 4), ky, kw))
|
||||
b.append('<text class="nj-charts-cell nj-charts-cell--small" x="%g" y="%g" text-anchor="middle">%s</text></g>' % (8 + i * (kw + 4) + kw / 2, ky + 14, esc(lab)))
|
||||
nx = 8 + len(HEAT_LABELS) * (kw + 4) + 12
|
||||
b.append('<rect class="nj-heat-na" x="%g" y="%g" width="%g" height="20" rx="3"/>' % (nx, ky, 40))
|
||||
b.append('<text class="nj-charts-tick" x="%g" y="%g">n/a</text>' % (nx + 20, ky + 14))
|
||||
b.append('<text class="nj-charts-tick nj-charts-tick--l" x="%g" y="%g">no API for it</text>' % (nx + 48, ky + 14))
|
||||
write("perf_blog_usecases_%s.svg" % platform, W, ky + 28, "nj-charts--blog nj-charts--heat", "nj-blog-uc-" + platform, title,
|
||||
"Table of relative times, libraries by use case. " + "; ".join(desc) + ".", b)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
swar()
|
||||
overlap()
|
||||
digits()
|
||||
heldout()
|
||||
if OVERVIEW:
|
||||
overview()
|
||||
distribution()
|
||||
if TIMELINE:
|
||||
timeline()
|
||||
if CLIFFS:
|
||||
cliffs()
|
||||
price()
|
||||
for platform, title in UC_PLATFORMS:
|
||||
if (HERE / "data" / ("perf_usecases_%s.json" % platform)).exists():
|
||||
heatmap(platform, title)
|
||||
@@ -1,66 +0,0 @@
|
||||
"""Prints the tables of Appendix E of home/blog/how_3_13_0_got_faster.md (comparison with other libraries) as Markdown,
|
||||
from data/perf_usecases_<platform>.json, which tests/benchmarks/json_view/others/summarize.py --json writes.
|
||||
|
||||
Usage: python3 scripts/figures/perf_blog_tables.py <platform> [title]
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from perf_blog import normalize_usecases
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
FILES = [("twitter", "`twitter.json`"), ("citm_catalog", "`citm_catalog.json`"), ("canada", "`canada.json`"),
|
||||
("jeopardy", "`jeopardy.json`"), ("status", "one status (2.5 KB)")]
|
||||
USE_CASES = [("validate", "validate"), ("sum", "sum"), ("select", "select"), ("edit", "edit"), ("minify", "minify"),
|
||||
("write", "write")]
|
||||
NAMES = {"nlohmann json_document": "nlohmann/json `json_document`", "nlohmann json": "nlohmann/json `json`",
|
||||
"sonic-rs": "sonic-rs (Rust)", "simd-json": "simd-json (Rust)", "serde_json": "serde_json (Rust)"}
|
||||
|
||||
|
||||
def fmt(us):
|
||||
if us >= 10000:
|
||||
return "{:,.0f}".format(us)
|
||||
if us >= 100:
|
||||
return "{:,.0f}".format(us)
|
||||
return "%.1f" % us
|
||||
|
||||
|
||||
def table(data, uc, indent):
|
||||
files = [f for f, _ in FILES if f in data.get(uc, {})]
|
||||
libs = list(data[uc][files[0]].keys())
|
||||
jd = lambda f: data[uc][f]["nlohmann json_document"]["best"]["us"]
|
||||
libs.sort(key=lambda l: sum(((data[uc][f][l]["best"] or data[uc][f][l]["best_any"])["us"] / jd(f)) for f in files))
|
||||
head = "| library | variant | " + " | ".join(n for f, n in FILES if f in files) + " |"
|
||||
rows = [head, "| --- | --- | " + " | ".join("--:" for _ in files) + " |"]
|
||||
for lib in libs:
|
||||
best = [data[uc][f][lib]["best"] for f in files]
|
||||
anyv = [data[uc][f][lib]["best_any"] for f in files]
|
||||
names = sorted({b["variant"] for b in best if b} | {a["variant"] + " [%s]" % a["mark"] for b, a in zip(best, anyv) if a["mark"] and (not b or a["us"] < b["us"])})
|
||||
cells = []
|
||||
for b, a in zip(best, anyv):
|
||||
c = fmt(b["us"]) if b else "–"
|
||||
if a["mark"] and (not b or a["us"] < b["us"] * 0.97):
|
||||
c += " (%s %s)" % (a["mark"], fmt(a["us"]))
|
||||
cells.append(c)
|
||||
bold = "**%s**" if lib == "nlohmann json_document" else "%s"
|
||||
rows.append("| %s | %s | %s |" % (bold % NAMES.get(lib, lib), ", ".join(names), " | ".join(cells)))
|
||||
return "\n".join(indent + r for r in rows)
|
||||
|
||||
|
||||
def main():
|
||||
platform = sys.argv[1]
|
||||
data = json.load((HERE / "data" / ("perf_usecases_%s.json" % platform)).open())
|
||||
data = normalize_usecases(data) # the same choices as the figure
|
||||
out = []
|
||||
for uc, label in USE_CASES:
|
||||
if uc not in data:
|
||||
continue
|
||||
out.append("**%s**\n" % label)
|
||||
out.append(table(data, uc, ""))
|
||||
out.append("")
|
||||
print("\n".join(out))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -22,19 +22,24 @@ P = "nj-exceptions-"
|
||||
TRIGGERS = {
|
||||
"push": ("every push / PR", "push"),
|
||||
"pr": ("every PR", "push"),
|
||||
"merge": ("before merge", "push"),
|
||||
"nightly": ("nightly", "sched"),
|
||||
"sched": ("scheduled", "sched"),
|
||||
"cont": ("continuous", "cont"),
|
||||
}
|
||||
|
||||
# title, triggers, lines (at most 31 characters, so they fit a card of the three-column drawing)
|
||||
LANES = [
|
||||
("Build matrix", ["push"], [
|
||||
("Build matrix", ["push", "merge"], [
|
||||
"50+ compilers: GCC, Clang, MSVC,",
|
||||
"AppleClang, Intel, NVIDIA, ...",
|
||||
"C++11, 14, 17, 20, 23, and 26",
|
||||
"libc++ and libstdc++",
|
||||
"warnings: Clang -Weverything,",
|
||||
"GCC 300+ warnings",
|
||||
"a subset on every push and PR,",
|
||||
"all before merge; Intel, NVIDIA,",
|
||||
"CUDA, and ARM64 nightly",
|
||||
]),
|
||||
("Unit tests (doctest)", ["push"], [
|
||||
"every public API function",
|
||||
@@ -44,7 +49,7 @@ LANES = [
|
||||
"custom number, string, array,",
|
||||
"and object types",
|
||||
]),
|
||||
("Coverage", ["push"], [
|
||||
("Coverage", ["nightly"], [
|
||||
"unit tests cover all lines",
|
||||
"of the code base",
|
||||
]),
|
||||
@@ -53,11 +58,11 @@ LANES = [
|
||||
"Clang Static Analyzer (52",
|
||||
"checkers), IWYU, Codacy",
|
||||
"CodeQL, Semgrep, Flawfinder",
|
||||
"(also scheduled)",
|
||||
"(also scheduled); Infer nightly",
|
||||
]),
|
||||
("Dynamic analysis", ["push"], [
|
||||
("Dynamic analysis", ["push", "nightly"], [
|
||||
"runtime assertions",
|
||||
"Valgrind (Memcheck)",
|
||||
"Valgrind (Memcheck), nightly",
|
||||
"address and undefined behavior",
|
||||
"sanitizers, integer overflow,",
|
||||
"nullability violations",
|
||||
@@ -178,7 +183,7 @@ def drawing(W, cols, suffix):
|
||||
defs = ('<defs><marker id="%s" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">'
|
||||
'<path class="fg-head" d="M0 1 L10 5 L0 9 z"/></marker></defs>' % mid)
|
||||
tid, did = "nj-qa-title-" + suffix, "nj-qa-desc-" + suffix
|
||||
desc = ("Every push or pull request starts these checks in parallel: " +
|
||||
desc = ("A push or pull request starts these checks; the badges say when each runs: " +
|
||||
"; ".join("%s (%s): %s" % (t, ", ".join(TRIGGERS[k][0] for k in trig), " ".join(lines)) for t, trig, lines in LANES) +
|
||||
". When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open.")
|
||||
out = ['<svg class="nj-fig %sqa %sqa--%s" viewBox="0 0 %d %d" role="img" aria-labelledby="%s %s" xmlns="http://www.w3.org/2000/svg">'
|
||||
|
||||
@@ -138,9 +138,6 @@ the `View*` benchmarks (in `src/benchmarks_view.cpp`) are only built if the dire
|
||||
Only benchmarks present in both result files are compared, so for older releases, either filter the benchmarks or
|
||||
build that release's own `tests/benchmarks` against its own header.
|
||||
|
||||
To find out *which commit* changed a number, [`history/`](history/README.md) times one fixed program against the
|
||||
header of every commit that changed it.
|
||||
|
||||
## Getting stable numbers
|
||||
|
||||
- Build and run both versions on the same machine with the same compiler and Google Benchmark, one right after the
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Performance history
|
||||
|
||||
The benchmarks in [`tests/benchmarks`](../README.md) compare two versions. The program here answers a different
|
||||
question: *which commit* made something faster or slower. `history.cpp` is one fixed benchmark that uses only API
|
||||
3.12.0 already has. `history.py` compiles it against the `single_include` of every first-parent commit that changed
|
||||
`json.hpp` or `json_view.hpp`, runs all of them interleaved, and writes one CSV row per commit with its pull request.
|
||||
The timeline in the post [How 3.13.0 got faster](https://json.nlohmann.me/home/blog/how_3_13_0_got_faster/) comes from
|
||||
it. It is not built by CMake or run by CI.
|
||||
|
||||
## Workloads
|
||||
|
||||
| name | what it does |
|
||||
|---|---|
|
||||
| `parse_twitter`, `parse_citm`, `parse_canada` | `json::parse()` of a `std::string` (`citm_catalog.json` as distributed is indented by four spaces) |
|
||||
| `parse_citm_compact` | the same with a minified copy of `citm_catalog.json` |
|
||||
| `parse_twitter_ifstream` | `json::parse()` of an `std::ifstream`, opening the file included |
|
||||
| `accept_twitter` | `json::accept()` |
|
||||
| `view_parse_*` | `json_document::parse()`; only where the header has `json_view.hpp` |
|
||||
| `dump_twitter`, `dump_citm`, `dump_canada`, `dump4_citm` | `dump()` and `dump(4)` |
|
||||
| `from_cbor_twitter`, `to_cbor_twitter` | read and write CBOR |
|
||||
| `copy_destroy_citm` | copy a parsed document and destroy the copy |
|
||||
| `equal_citm` | copy a parsed document and compare it with `==` |
|
||||
|
||||
Each workload runs in batches of at least 20 ms; the program prints the median of 9 batches in microseconds per call.
|
||||
|
||||
## Running it
|
||||
|
||||
```sh
|
||||
mkdir -p ~/history/data
|
||||
cp <json_test_data>/nativejson-benchmark/{twitter,citm_catalog,canada}.json ~/history/data/
|
||||
python3 history.py build --repo ../../.. --work ~/history # about 300 builds, a few minutes in parallel
|
||||
caffeinate -i python3 history.py run --work ~/history --rounds 4 # about 1 h 45 min on an M1 Max (about 4 s per binary and round)
|
||||
python3 history.py summarize --work ~/history > history.csv
|
||||
```
|
||||
|
||||
`--extra DIR` adds one more header directory, such as an amalgamation of `develop` with open pull requests merged
|
||||
in. `run` waits whenever the 1-minute load average is 4 or more.
|
||||
|
||||
## Reading the results
|
||||
|
||||
A single commit can move a workload by a few percent through code layout alone: the functions it did not touch
|
||||
move to other addresses. Read a change as a step only if it is larger than that and stays. To check one, time the
|
||||
two commits against each other with more rounds, or compare instruction counts.
|
||||
@@ -1,98 +0,0 @@
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||
// | | |__ | | | | | | version 3.12.0
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// One fixed benchmark, compiled against the json.hpp of every commit that changed it (see README.md).
|
||||
// It uses only API that 3.12.0 has; the json_document rows exist only where the header has json_view.hpp.
|
||||
// Usage: history <dir with twitter.json, citm_catalog.json, canada.json and citm_compact.json>
|
||||
// Prints one line per workload: the name and the median of 9 batches in microseconds per call.
|
||||
#include <nlohmann/json.hpp>
|
||||
#if __has_include(<nlohmann/json_view.hpp>) && !defined(HISTORY_NO_VIEW)
|
||||
#include <nlohmann/json_view.hpp>
|
||||
#define HISTORY_VIEW 1
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using nlohmann::json;
|
||||
static std::string slurp(const std::string& p)
|
||||
{
|
||||
std::ifstream f(p, std::ios::binary);
|
||||
std::stringstream s;
|
||||
s << f.rdbuf();
|
||||
return s.str();
|
||||
}
|
||||
static volatile std::size_t sink;
|
||||
|
||||
static void bench(const char* name, const std::function<std::size_t()>& f)
|
||||
{
|
||||
using clk = std::chrono::steady_clock;
|
||||
sink = f(); // warm up
|
||||
std::size_t n = 1;
|
||||
for (;;)
|
||||
{
|
||||
auto t0 = clk::now();
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
{
|
||||
sink = f();
|
||||
}
|
||||
double dt = std::chrono::duration<double>(clk::now() - t0).count();
|
||||
if (dt > 0.02)
|
||||
{
|
||||
break;
|
||||
}
|
||||
n *= 2;
|
||||
}
|
||||
std::vector<double> v;
|
||||
for (int b = 0; b < 9; ++b)
|
||||
{
|
||||
auto t0 = clk::now();
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
{
|
||||
sink = f();
|
||||
}
|
||||
v.push_back(std::chrono::duration<double, std::micro>(clk::now() - t0).count() / n);
|
||||
}
|
||||
std::sort(v.begin(), v.end());
|
||||
std::cout << name << ' ' << std::fixed << std::setprecision(3) << v[4] << '\n';
|
||||
}
|
||||
|
||||
int main(int, char** argv)
|
||||
{
|
||||
std::string d = argv[1];
|
||||
const std::string tw = slurp(d + "/twitter.json"), ci = slurp(d + "/citm_catalog.json"),
|
||||
ca = slurp(d + "/canada.json"), cii = slurp(d + "/citm_compact.json");
|
||||
const json jtw = json::parse(tw), jci = json::parse(ci), jca = json::parse(ca);
|
||||
const std::vector<std::uint8_t> cbtw = json::to_cbor(jtw);
|
||||
|
||||
bench("parse_twitter", [&] { return json::parse(tw).size(); });
|
||||
bench("parse_citm", [&] { return json::parse(ci).size(); });
|
||||
bench("parse_canada", [&] { return json::parse(ca).size(); });
|
||||
bench("parse_citm_compact", [&] { return json::parse(cii).size(); });
|
||||
bench("parse_twitter_ifstream", [&] { std::ifstream f(d + "/twitter.json"); return json::parse(f).size(); });
|
||||
bench("accept_twitter", [&] { return static_cast<std::size_t>(json::accept(tw)); });
|
||||
#ifdef HISTORY_VIEW
|
||||
bench("view_parse_twitter", [&] { const auto doc = nlohmann::json_document::parse(tw); return doc.root().size(); });
|
||||
bench("view_parse_citm", [&] { const auto doc = nlohmann::json_document::parse(ci); return doc.root().size(); });
|
||||
bench("view_parse_canada", [&] { const auto doc = nlohmann::json_document::parse(ca); return doc.root().size(); });
|
||||
#endif
|
||||
bench("dump_twitter", [&] { return jtw.dump().size(); });
|
||||
bench("dump_citm", [&] { return jci.dump().size(); });
|
||||
bench("dump_canada", [&] { return jca.dump().size(); });
|
||||
bench("dump4_citm", [&] { return jci.dump(4).size(); });
|
||||
bench("from_cbor_twitter", [&] { return json::from_cbor(cbtw).size(); });
|
||||
bench("to_cbor_twitter", [&] { return json::to_cbor(jtw).size(); });
|
||||
bench("copy_destroy_citm", [&] { json c = jci; return c.size(); });
|
||||
bench("equal_citm", [&] { json c = jci; return static_cast<std::size_t>(c == jci); });
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# __ _____ _____ _____
|
||||
# __| | __| | | | JSON for Modern C++ (supporting code)
|
||||
# | | |__ | | | | | | version 3.12.0
|
||||
# |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Time one fixed benchmark against the json.hpp of every commit that changed it.
|
||||
|
||||
Usage:
|
||||
history.py build --repo REPO --work DIR [--from v3.12.0] [--to origin/develop] [--extra INCLUDE_DIR]
|
||||
history.py run --work DIR [--rounds 4]
|
||||
history.py summarize --work DIR [--repo REPO] > history.csv
|
||||
|
||||
build: lists the first-parent commits between --from and --to that changed single_include/nlohmann/json.hpp or
|
||||
json_view.hpp, extracts single_include/ of each (and of --from itself), and compiles history.cpp against it into
|
||||
DIR/bin/NNN, NNN being the line of the commit in DIR/commits.txt. --extra adds one more header directory at the end,
|
||||
for example an amalgamation of develop with open pull requests merged in. It also writes the input files to DIR/data
|
||||
(the nativejson-benchmark files from the test data, which must be in DIR/data already, plus a minified copy of
|
||||
citm_catalog.json).
|
||||
|
||||
run: runs every binary once per round, in a new random order each round, and only while the 1-minute load average is
|
||||
below 4. Output: DIR/res/NNN-R.txt.
|
||||
|
||||
summarize: the median over the rounds per binary and workload, as CSV with the commit, its date and its pull request.
|
||||
|
||||
Only the Python 3 standard library is used; a C++17 compiler (c++) and git are needed.
|
||||
"""
|
||||
import argparse
|
||||
import concurrent.futures
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import statistics
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
FLAGS = ["-std=c++17", "-O3", "-DNDEBUG", "-w"]
|
||||
|
||||
|
||||
def git(repo, *args):
|
||||
return subprocess.run(["git", "-C", str(repo), *args], check=True, capture_output=True, text=True).stdout
|
||||
|
||||
|
||||
def build_one(work, idx, rev, repo):
|
||||
hdr = work / "hdr" / idx
|
||||
hdr.mkdir(parents=True, exist_ok=True)
|
||||
if rev.startswith("dir:"):
|
||||
subprocess.run(["cp", "-R", rev[4:] + "/nlohmann", str(hdr)], check=True)
|
||||
else:
|
||||
archive = subprocess.run(["git", "-C", str(repo), "archive", rev, "single_include/nlohmann"],
|
||||
check=True, capture_output=True).stdout
|
||||
subprocess.run(["tar", "-x", "-C", str(hdr), "--strip-components=1"], input=archive, check=True)
|
||||
out = work / "bin" / idx
|
||||
cmd = ["c++", *FLAGS, "-I", str(hdr), str(HERE / "history.cpp"), "-o", str(out)]
|
||||
# json_view.hpp of the first commits that had it may not compile with history.cpp: time json.hpp alone then
|
||||
if subprocess.run(cmd, capture_output=True).returncode != 0:
|
||||
if subprocess.run(cmd[:-4] + ["-DHISTORY_NO_VIEW"] + cmd[-4:], capture_output=True).returncode != 0:
|
||||
return "FAIL %s %s" % (idx, rev)
|
||||
return None
|
||||
|
||||
|
||||
def build(a):
|
||||
work, repo = Path(a.work), Path(a.repo)
|
||||
(work / "bin").mkdir(parents=True, exist_ok=True)
|
||||
revs = [a.__dict__["from"]] + git(repo, "log", "--first-parent", "--reverse", "--format=%H",
|
||||
"%s..%s" % (a.__dict__["from"], a.to), "--",
|
||||
"single_include/nlohmann/json.hpp", "single_include/nlohmann/json_view.hpp").split()
|
||||
if a.extra:
|
||||
revs.append("dir:" + str(Path(a.extra).resolve()))
|
||||
(work / "commits.txt").write_text("\n".join(revs) + "\n")
|
||||
data = work / "data"
|
||||
citm = json.loads((data / "citm_catalog.json").read_text(encoding="utf-8"))
|
||||
(data / "citm_compact.json").write_text(json.dumps(citm, separators=(",", ":"), ensure_ascii=False), encoding="utf-8")
|
||||
with concurrent.futures.ThreadPoolExecutor(os.cpu_count()) as ex:
|
||||
for r in ex.map(lambda p: build_one(work, "%03d" % p[0], p[1], repo), enumerate(revs)):
|
||||
if r:
|
||||
print(r, file=sys.stderr)
|
||||
|
||||
|
||||
def load():
|
||||
out = subprocess.run(["sysctl", "-n", "vm.loadavg"], capture_output=True, text=True).stdout
|
||||
return float(out.split()[1]) if out else os.getloadavg()[0]
|
||||
|
||||
|
||||
def run(a):
|
||||
work = Path(a.work)
|
||||
(work / "res").mkdir(exist_ok=True)
|
||||
bins = sorted(p.name for p in (work / "bin").iterdir())
|
||||
for r in range(1, a.rounds + 1):
|
||||
random.shuffle(bins)
|
||||
for b in bins:
|
||||
while load() >= 4:
|
||||
time.sleep(15)
|
||||
out = subprocess.run([str(work / "bin" / b), str(work / "data")], check=True, capture_output=True, text=True)
|
||||
(work / "res" / ("%s-%d.txt" % (b, r))).write_text(out.stdout)
|
||||
print("round %d done" % r, file=sys.stderr)
|
||||
|
||||
|
||||
def summarize(a):
|
||||
work = Path(a.work)
|
||||
revs = (work / "commits.txt").read_text().split()
|
||||
times, names = {}, []
|
||||
for f in sorted((work / "res").glob("*.txt")):
|
||||
idx = int(f.name.split("-")[0])
|
||||
for line in f.read_text().splitlines():
|
||||
name, us = line.split()
|
||||
if name not in names:
|
||||
names.append(name)
|
||||
times.setdefault((idx, name), []).append(float(us))
|
||||
w = csv.writer(sys.stdout, lineterminator="\n")
|
||||
w.writerow(["index", "commit", "date", "pr", "subject"] + names)
|
||||
for idx, rev in enumerate(revs):
|
||||
if rev.startswith("dir:"):
|
||||
sha, date, pr, subject = "candidate", "", "", "develop + open pull requests"
|
||||
else:
|
||||
sha, date, subject = git(a.repo, "log", "-1", "--format=%h%x09%cs%x09%s", rev).strip().split("\t")
|
||||
m = re.search(r"\(#(\d+)\)$", subject)
|
||||
pr = m.group(1) if m else ""
|
||||
w.writerow([idx, sha, date, pr, subject] +
|
||||
["%.3f" % statistics.median(times[(idx, n)]) if (idx, n) in times else "" for n in names])
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
sub = p.add_subparsers(dest="cmd", required=True)
|
||||
b = sub.add_parser("build")
|
||||
b.add_argument("--repo", required=True)
|
||||
b.add_argument("--work", required=True)
|
||||
b.add_argument("--from", default="v3.12.0")
|
||||
b.add_argument("--to", default="origin/develop")
|
||||
b.add_argument("--extra")
|
||||
r = sub.add_parser("run")
|
||||
r.add_argument("--work", required=True)
|
||||
r.add_argument("--rounds", type=int, default=4)
|
||||
s = sub.add_parser("summarize")
|
||||
s.add_argument("--work", required=True)
|
||||
s.add_argument("--repo", default=str(HERE.parents[2]))
|
||||
a = p.parse_args()
|
||||
{"build": build, "run": run, "summarize": summarize}[a.cmd](a)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,249 +0,0 @@
|
||||
# json_document against other JSON libraries
|
||||
|
||||
[`compare.py`](../compare.py) compares `json_document` with yyjson, simdjson and Boost.JSON. The programs here add
|
||||
sonic-cpp, RapidJSON and Glaze in C++, and sonic-rs, simd-json and serde_json in Rust, for the post
|
||||
[How 3.13.0 got faster](https://json.nlohmann.me/home/blog/how_3_13_0_got_faster/#how-it-compares). They are not
|
||||
built by CMake or run by CI.
|
||||
|
||||
## What is measured
|
||||
|
||||
The programs compare **use cases**, not library functions. A library may implement a use case in every reasonable way
|
||||
(another API, SAX events, in-situ parsing, a struct binding); each such way is a *variant*, named
|
||||
`<library>: <variant>` (`yyjson: insitu (copy)`, `RapidJSON: SAX`, `nlohmann json_document: accept`). The report shows
|
||||
each library's fastest correct variant. `nlohmann json` (`basic_json`) and `nlohmann json_document` (with
|
||||
`json_view`) count as two libraries.
|
||||
|
||||
| use case | what it does |
|
||||
|---|---|
|
||||
| `validate` | is this text valid JSON? returns a bool |
|
||||
| `sum` | visit every value, convert every number, touch every string and key; sum all numbers in document order |
|
||||
| `select` | read a few fields of every record (the fields of `bench_view.cpp`, e.g. `id`, `user.screen_name` and `retweet_count` of every status) |
|
||||
| `edit` | change some values of every record and write the document as compact JSON (see below) |
|
||||
| `minify` | text in, compact text out |
|
||||
| `write` | write a document parsed beforehand as compact JSON; only the writing is timed |
|
||||
|
||||
The edits:
|
||||
|
||||
| file | edit |
|
||||
|---|---|
|
||||
| `twitter.json` | for every element of `statuses`: `retweet_count` + 1, erase `entities`, add `"seen": true` |
|
||||
| status | the same edit on the one status |
|
||||
| `citm_catalog.json` | for every element of `performances`: `start` + 1, erase `seatMapImage`, add `"seen": true` |
|
||||
| `canada.json` | `features[0].properties.name` = `"Kanada"`; append `[0.5,0.25]` to the first ring (`geometry.coordinates[0]`) of every feature |
|
||||
| `jeopardy.json` | for every record: `value` = `null`, erase `air_date`, add `"seen": true` |
|
||||
|
||||
The files are `twitter.json`, `citm_catalog.json`, `canada.json` (nativejson-benchmark), `jeopardy.json`, the first
|
||||
status of `twitter.json` (`status`; written by `json::dump()`, timed in batches of 200), and `twitter_min` and
|
||||
`citm_catalog_min`: `twitter.json` and `citm_catalog.json` with all whitespace outside strings removed, built in memory at
|
||||
startup by the same small function in both programs (`strip_ws`; the bytes inside strings are untouched). The minified
|
||||
files use the select and edit of their originals.
|
||||
|
||||
### Input contract
|
||||
|
||||
The input is a `const std::string` holding the file, with at least 64 bytes of spare capacity (`reserve`), so libraries
|
||||
that need padding (simdjson) can use it without a copy. A variant that modifies the input (in-situ parsing: yyjson
|
||||
`YYJSON_READ_INSITU`, RapidJSON `ParseInsitu`, simd-json) copies it inside the timed call; its name says `(copy)`.
|
||||
The C++ in-situ variants also run as `(copy untimed)`: the copy is made before the timer starts and freed after it
|
||||
stops, as for a program that reads a file into a buffer it owns and no longer needs. They are reported but never
|
||||
chosen as a library's best. `json_document`'s `parse_copy` is the opposite case: a document that owns a copy of its
|
||||
text.
|
||||
Each timed call starts from the text and frees everything it built, except variants named `(reused)` or
|
||||
`(reused allocator)`, which keep a parser, document or allocator across calls (simdjson's reused parsers,
|
||||
`json_document::read()`, Boost.JSON's reset `parser` and `basic_parser`, yyjson's dynamic allocator, RapidJSON's
|
||||
user-buffer allocators, simd-json's buffers). These are reported but never chosen as a library's best;
|
||||
`summarize.py` reports each library's best reused variant separately. In Rust, the input is the file as bytes (`&[u8]`), so every library
|
||||
has to validate UTF-8 itself.
|
||||
|
||||
### Correctness rules
|
||||
|
||||
Before timing, every variant runs on the file and must produce the right result:
|
||||
|
||||
- `validate`: `true`.
|
||||
- `sum`: the same number of values, the same number of string and key bytes, and a sum of all numbers that is
|
||||
bit-identical to `json_document`'s (document order), so every number is converted exactly; variants that visit
|
||||
objects in another order (`nlohmann json: parse`, simd-json and serde_json values) are compared within 1e-9.
|
||||
- `select`: the same value as `json_document`. A variant that does not convert numbers (`(raw numbers)`,
|
||||
`(numbers: none)`) has to convert the numbers it selects exactly itself.
|
||||
- `edit`, `minify`, `write`: the output, read with `json::parse`, compares equal (`==`) to the expected document (for
|
||||
`edit`, the edit applied to a `json` value; floats compare exactly, so every float must be written exactly). In
|
||||
Rust, `serde_json::Value` (with `float_roundtrip`) is the reference.
|
||||
|
||||
A variant that gives a wrong result on a file, or crashes on it, is printed as
|
||||
`excluded: <file> <use case> | <variant> | <reason>` and not timed.
|
||||
|
||||
### Validation levels
|
||||
|
||||
Except for `write`, every variant is also probed with four malformed inputs derived from each file: the file
|
||||
truncated by one byte (after trailing whitespace), the file followed by ` ]x` (trailing garbage), a stray `,` before
|
||||
the first `}` (before the last `]` in a file without objects), and a `0xFF` byte inside a string value (the first in
|
||||
the second half of the file, or the last one; never a key, so that a variant that accepts the byte still finds the
|
||||
keys it looks up; a file without string values gets no `0xFF` probe). The probes run in a child process, so a crash is caught. The result is the
|
||||
variant's *validation level*, printed in its cell (`sonic-cpp: Document [no UTF-8] 380.1us`):
|
||||
|
||||
| level | meaning |
|
||||
|---|---|
|
||||
| `full` | rejects all four probes |
|
||||
| `no UTF-8` | rejects the structural probes, accepts the `0xFF` byte |
|
||||
| `partial` | accepts the truncated input, the trailing garbage or the stray comma, or crashes on any probe |
|
||||
| `n/a` | `write`: there is no input to validate (counts as `full`) |
|
||||
|
||||
What a variant accepts is printed as `level: <file> <use case> | <variant> | <level> | <what>`. A variant's level in
|
||||
the summary is the worst it got for any file. UTF-8 validation is enabled where a library has a switch (RapidJSON
|
||||
`kParseValidateEncodingFlag`; the `(no encoding check)` variants leave it off). sonic-cpp 1.0.2 cannot validate
|
||||
UTF-8 at all; serde_json does not validate UTF-8 in the parts it skips (`IgnoredAny`, unknown struct fields) unless
|
||||
the input is checked with `std::str::from_utf8` first (the `from_utf8 + ...` variants).
|
||||
|
||||
The sum and select reference values are printed as `check ... reference:` lines; `summarize.py` warns if the C++ and
|
||||
Rust logs disagree.
|
||||
|
||||
The four probes do not cover everything a parser can get wrong. `--conformance <dir>` runs every `validate` variant
|
||||
on every file of [JSONTestSuite](https://github.com/nst/JSONTestSuite)'s `test_parsing` (json_test_data has it as
|
||||
`nst_json_testsuite2/test_parsing`) and prints `conformance: <file> | <variant> | accepted|rejected|crashed`; a `y_`
|
||||
file must be accepted, an `n_` file rejected, and an `i_` file may go either way. bench_all runs each call in a child
|
||||
process (a call that hangs for 60 s counts as crashed); a stack overflow aborts bench_rs, so `conformance-rs.sh`
|
||||
runs it one file per process and, for a file that aborts, one variant per process (`CONF_VARIANT`). The trailing
|
||||
garbage probe was added after this check: Glaze reads anything after the value unless `validate_trailing_whitespace`
|
||||
is set.
|
||||
|
||||
### Variants
|
||||
|
||||
Level on the Mac in brackets where it is not `full` (`P` = partial, `U` = no UTF-8); every `write` variant is `n/a`.
|
||||
|
||||
| library | validate | sum | select | edit | minify | write |
|
||||
|---|---|---|---|---|---|---|
|
||||
| nlohmann json_document | `accept`, `parse`, `read (reused)` | `parse`, `parse_copy`, `read (reused)` | `parse`, `parse_copy`, `structs (from_json)`, `read (reused)` | `editable`, `editable (source numbers)` (`json_editable_document`: set/erase, `dump` with `number_format::source`) | `parse + dump`, `parse_copy + dump`, `parse + dump (source numbers)`, `read + dump (reused)` | `dump`, `dump (source numbers)` |
|
||||
| nlohmann json | `accept`, `parse` | `parse`, `sax` | `parse`, `structs (from_json)` | `parse`, `ordered_json` | `parse + dump` | `dump` |
|
||||
| yyjson | `read`, `insitu (copy)`, `insitu (copy untimed)`, `read (raw numbers)`, `read (reused allocator)` | `read`, `insitu (copy)`, `insitu (copy untimed)`, `read (reused allocator)` | `read`, `insitu (copy)`, `insitu (copy untimed)`, `read (raw numbers)`, `read (reused allocator)` | `mut copy`, `insitu (copy) + mut copy` (`yyjson_doc_mut_copy`), `insitu (copy untimed) + mut copy` | `read + write`, `insitu (copy) + write`, `insitu (copy untimed) + write`, `read (raw numbers) + write`, `read + write (reused allocator)` | `write` |
|
||||
| simdjson | `DOM`, `DOM (reused)` | `DOM`, `DOM (reused)`, `On-Demand`, `On-Demand (reused)` | `DOM`, `DOM (reused)`, `On-Demand` [P], `On-Demand (reused)` [P], `On-Demand structs` [P], `On-Demand (key selectors)` [P] | n/a (no mutable document) | `DOM + to_string`, `DOM (reused) + to_string`, `minify` [P] | `to_string` |
|
||||
| RapidJSON | `SAX` (null handler), `Document`, `insitu (copy)`, `insitu (copy untimed)`, `SAX (string stream)`, `SAX (default precision)`, `SAX (string stream, default precision)`, `SAX (raw numbers)`, `Document (reused allocator)` | `Document`, `SAX`, `insitu (copy)`, `insitu (copy untimed)`, `SAX (string stream)`, `Document (reused allocator)` | `Document`, `insitu (copy)`, `insitu (copy untimed)`, `Document (string stream)`, `Document (raw numbers)`, `Document (reused allocator)` | `Document`, `insitu (copy)`, `insitu (copy untimed)`, `Document (string stream)` | `Document + Writer`, `SAX to Writer`, `SAX to Writer (string stream)`, `SAX to Writer (raw numbers)`, `Document + Writer (reused allocator)` | `Writer` |
|
||||
| RapidJSON, `(no encoding check)` | the same [U] | the same [U] | the same [U] | the same [U] | the same [U] | |
|
||||
| sonic-cpp | `Document` [U] | `Document` [U] | `Document` [U] | `Document` [U] | `Document + Serialize` [U] | `Serialize` |
|
||||
| Glaze | `validate_json`, `generic` [P], `generic (double)` [P], `generic (strict)`, `generic (double, strict)` | `generic` [P], `generic (double)` [P], `generic (strict)`, `generic (double, strict)`, `lazy_json` [P], `lazy_json (string_view)` (x) | `structs` [P], `structs (validate_skipped)`, `generic` [P], `generic (double)` [P], `generic (strict)`, `generic (double, strict)`, `lazy_json` [P], `lazy_json (string_view)` (x) | `generic` [P], `generic (double)` (x), `generic (strict)`, `generic (double, strict)` (x) | `generic` [P], `generic (double)` (x), `generic (strict)`, `generic (double, strict)` (x), `minify_json` [P] | `generic`, `generic (double)` (x), `generic (strict)`, `generic (double, strict)` (x) |
|
||||
| Boost.JSON | `SAX` (`basic_parser`), `parse`, `SAX (numbers: none)`, `parse (numbers: none)`, `SAX (reused)`, `parser (reused)` | `parse`, `SAX`, `SAX (reused)`, `parser (reused)` | `parse`, `parse (numbers: none)` (x), `parser (reused)`, `parse_into structs` | `parse` | `parse + serialize`, `parser (reused) + serialize` | `serialize` |
|
||||
| serde_json | `IgnoredAny` [U], `from_utf8 + IgnoredAny`, `Value` | `visitor`, `Value` | `structs` [U], `from_utf8 + structs`, `Value` | `Value` | `Value` | `Value` |
|
||||
| sonic-rs | `IgnoredAny`, `Value` | `visitor`, `Value` | `structs`, `Value` | `Value` | `Value` | `Value` |
|
||||
| simd-json | `tape (copy)`, `borrowed (copy)`, `tape (reused)` | `visitor (copy)`, `borrowed (copy)`, `borrowed (reused)` | `structs (copy)`, `borrowed (copy)` | `owned (copy)`, `borrowed (copy)` | `borrowed (copy)` | `borrowed` |
|
||||
|
||||
(x): excluded for a wrong result on some file, and so in the summary for every file: `generic (double)` loses the
|
||||
64-bit ids of `twitter.json` when it writes them; `lazy_json (string_view)` reads the raw bytes of a string, so escaped
|
||||
strings have the wrong length (`sum`, and the `"` in 19,077 `jeopardy.json` categories in `select`);
|
||||
`numbers: none` reads every number as 0.
|
||||
|
||||
`structs` read into types that declare only the fields `select` uses and hold the same data: nlohmann/json's
|
||||
`from_json()` of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` macro (from a `json` value or from a `json_document`'s view)
|
||||
reads into `nsel`, where the arrays and objects that are only counted (`seatCategories`, the values of `events`,
|
||||
`coordinates`) are a `count_only` holding their size. Glaze reads into the same types (reflected; `count_only` has a
|
||||
reader that skips and counts the elements; `error_on_unknown_keys = false`, and with `validate_skipped` to validate
|
||||
what it skips), and so does simdjson On-Demand (`get<T>()` with `tag_invoke`, fields in document order,
|
||||
`count_elements()`/`count_fields()`). serde derive reads into the same fields with a `Count` that counts with
|
||||
`IgnoredAny` (and a `BTreeMap`, as `std::map`). Boost.JSON's `parse_into` has no type that skips any value, so its
|
||||
counted members only count what it converts into them: `seatCategories` into a counting sequence of an empty described
|
||||
struct, `coordinates` into three levels of counting sequences down to `double`, and the `events` values into an empty
|
||||
described struct, so their members are not counted. `key selectors` are simdjson 5.0's `object::for_each<"k1",
|
||||
...>`, which walks each object once and matches keys with a compile-time perfect hash. `visitor` is a serde
|
||||
`DeserializeSeed` that sums without building a value; `SAX` and `sax` are the libraries' event interfaces with a
|
||||
summing (or, for `validate`, an empty) handler. RapidJSON parses with `kParseFullPrecisionFlag` (correctly rounded
|
||||
floats; without it, sums and written floats are wrong) and Boost.JSON with `number_precision::precise`, as every other
|
||||
library rounds correctly by default; only `validate`, which reads no number, also has RapidJSON's `(default
|
||||
precision)`. RapidJSON's `Document::Parse(data, size)` and our `SAX` read through `EncodedInputStream<MemoryStream>`;
|
||||
`(string stream)` reads the NUL-terminated string through `StringStream`, as `Document::Parse(const char*)` does,
|
||||
where RapidJSON has a SIMD string scanner (used only without `kParseValidateEncodingFlag`).
|
||||
|
||||
Variants named `(raw numbers)` or `(numbers: none)` use a library's mode that validates numbers without converting
|
||||
them (yyjson `YYJSON_READ_NUMBER_AS_RAW`, RapidJSON `kParseNumbersAsStringsFlag`, Boost.JSON
|
||||
`number_precision::none`), as `json_document` converts a number only when it is read. In `select` they convert the
|
||||
selected numbers themselves (`std::from_chars`); Boost.JSON's `none` leaves no number text in its DOM, so it cannot.
|
||||
yyjson writes a raw number verbatim, so `read (raw numbers) + write` is exact. sonic-cpp 1.0.2 has no parse flags,
|
||||
and Glaze's generic DOM has no raw number mode (`validate_json` converts no number anyway). `(reused allocator)`:
|
||||
yyjson's `yyjson_alc_dyn_new()`, RapidJSON's `MemoryPoolAllocator`s over user buffers for the values and the parse
|
||||
stack; Boost.JSON's `parser (reused)` builds its value in a `monotonic_resource` over a buffer kept across calls. These
|
||||
buffers grow after a call that needed more, so the timed calls do not allocate. `generic (double)` is `glz::generic`,
|
||||
which stores every number as a double. The Glaze `(strict)` variants read with `validate_trailing_whitespace` (else
|
||||
Glaze accepts anything after the value) and write with `escape_control_characters` (else Glaze writes a string's
|
||||
control characters, e.g. U+0001, unescaped, which is not JSON; `gsoc-2018.json` has some).
|
||||
|
||||
| library | version | notes |
|
||||
|---|---|---|
|
||||
| `json_document`, `json` | this checkout | |
|
||||
| yyjson | 0.13.0 | |
|
||||
| simdjson | 5.1.1 | the single-header files of the tag |
|
||||
| sonic-cpp | 1.0.2 | |
|
||||
| RapidJSON | master 24b5e7a8b27f (2025-02-05) | |
|
||||
| Glaze | 9.1.0 | `generic_u64` and `generic` (owning DOMs, member order kept) |
|
||||
| Boost.JSON | 1.92.0 | monotonic resource |
|
||||
| sonic-rs, simd-json, serde_json | see `rust/Cargo.lock` | serde_json with `float_roundtrip` |
|
||||
|
||||
SHA-256 of the downloads:
|
||||
|
||||
```
|
||||
55f8a675397c505f9bee6c160e1c26b0085868f185d04d7a7727531fdbff4bd4 glaze-v9.1.0.tar.gz
|
||||
30edf9e47c417f653546c39295fdb66ba5f89fb37eb3780122c6ee66605e5837 sonic-cpp v1.0.2.tar.gz
|
||||
2d2601a82d2d3b7e143a3c8d43ef616671391034bc46891a9816b79cf2d3e7a8 rapidjson 24b5e7a8b27f42fa16b96fc70aade9106cf7102f.tar.gz
|
||||
34e0f62a2bc11ab20d601e8ca1cc2b2079503aa45119a19133d89d19b94a0fae yyjson 0.13.0.tar.gz
|
||||
f3e5ee5f39051960b5ce65762ee4b6919caf270675eb52240ebd92f21a5bcefd simdjson v5.1.1 singleheader/simdjson.h
|
||||
3ea5f501cef6c2e16e28095b566feeb56021ca473aaf50aad32102f45d734195 simdjson v5.1.1 singleheader/simdjson.cpp
|
||||
c4a3b310ddd2472416e091067166b0713be97c63f38c212c484ada022fd296ce boost_1_92_0.tar.gz
|
||||
```
|
||||
|
||||
### Timing
|
||||
|
||||
Every variant of a use case runs interleaved in every round, each timed call after an untimed one, and the best
|
||||
round is reported (the method of `bench_view.cpp`). The order of the variants changes in every round (a shuffle with a
|
||||
fixed seed; the first round keeps the listed order): on the Mac, a variant's time can depend on which variant ran
|
||||
before it, by up to 15 %, and a fixed order would give each variant the same neighbour in every round. `jeopardy.json` (50 MB) gets a fifth of the rounds (at least 3,
|
||||
at most the given number).
|
||||
|
||||
## Building and running
|
||||
|
||||
All libraries except yyjson and simdjson are used header-only. With the downloads unpacked into `DL`
|
||||
(`compare.py --download` fetches yyjson and Boost into its build directory, and simdjson 4.6.11, so take simdjson
|
||||
5.1.1's `singleheader` files from its tag):
|
||||
|
||||
```sh
|
||||
cc -O3 -DNDEBUG -c $DL/yyjson-0.13.0/src/yyjson.c -o yyjson.o
|
||||
c++ -std=c++17 -O3 -DNDEBUG -c $DL/simdjson-5.1.1/singleheader/simdjson.cpp -o simdjson.o
|
||||
c++ -std=c++23 -O3 -DNDEBUG -DRAPIDJSON_NEON \
|
||||
-I ../../../../include -I $DL/yyjson-0.13.0/src -I $DL/simdjson-5.1.1/singleheader -I $DL/boost_1_92_0 \
|
||||
-I $DL/glaze-9.1.0/include -I $DL/rapidjson/include -I $DL/sonic/include \
|
||||
bench_all.cpp yyjson.o simdjson.o -o bench_all
|
||||
./bench_all <json_test_data> 30 > mac-cpp-1.log
|
||||
|
||||
cd rust && cargo build --release --locked && ./target/release/bench_rs <json_test_data> 30 > ../mac-rs-1.log
|
||||
|
||||
python3 summarize.py mac-cpp-*.log --rust mac-rs-*.log --json mac.json
|
||||
```
|
||||
|
||||
With GCC 16 and Homebrew Clang on macOS, build the three steps with the same flags plus
|
||||
`--sysroot=$(xcrun --show-sdk-path)` (`gcc-16`, `g++-16`) or `-isysroot $(xcrun --show-sdk-path)`
|
||||
(`/opt/homebrew/opt/llvm/bin/clang`, `clang++`). The key selectors and simdjson's `tag_invoke` need C++20, so
|
||||
`bench_all.cpp` needs `-std=c++20` or newer.
|
||||
|
||||
Both programs take `<json_test_data> [rounds] [file] [use case]`: `./bench_all <json_test_data> 30 canada edit` times
|
||||
only the edit of `canada.json`; `""` stands for all files; the file names are `twitter`, `citm_catalog`, `canada`,
|
||||
`jeopardy`, `status`, `twitter_min` and `citm_catalog_min`. The checks cover only the selected files and use cases.
|
||||
bench_all uses `fork()` for the probes and the crash check (macOS, Linux).
|
||||
|
||||
`--files <dir> [rounds] [file] [use case]` runs `validate`, `sum`, `minify` and `write` (`select` and `edit` are
|
||||
defined only for the files above) on every `*.json` file of a directory, named by their stem; files under 500 KB are
|
||||
timed in batches of about 500 KB of input. It is meant for files the libraries were not tuned on, such as the
|
||||
`jsonexamples` of [simdjson-data](https://github.com/simdjson/simdjson-data) without `twitter.json`,
|
||||
`citm_catalog.json` and `canada.json`. `summarize.py` takes such logs as well.
|
||||
|
||||
On x86-64, use `-march=haswell -DRAPIDJSON_SSE42` instead of `-DRAPIDJSON_NEON` (sonic-cpp needs AVX2), pin the
|
||||
process to one core, and time one file per process. Glaze 9 needs `std::expected`, which Clang 18 and older cannot
|
||||
use from GCC 13's standard library (Clang 19 and newer can); `-DBENCH_NO_GLAZE=1` builds without it. For Rust, build
|
||||
with `RUSTFLAGS="-C target-cpu=haswell"` to match `-march=haswell`.
|
||||
|
||||
## Reading the results
|
||||
|
||||
A log line holds the file, the use case, and one cell per variant: `| <library>: <variant> [<level>] <time>us
|
||||
(<ratio>x)`, the ratio relative to the first variant of the line. `summarize.py` prints, for every use case and file,
|
||||
(a) per library the best `full` variant and, if faster, the best variant at any level, with their ratios to the best
|
||||
`full` `nlohmann json_document` variant (`(reused)` and `(reused allocator)` variants are never a library's best; a
|
||||
`reused:` line below the library shows its best reused variant in the same way), (b) all variants with their levels
|
||||
and times, and (c) what the variants below `full` accept, and the excluded variants. `--json` writes
|
||||
`{use case: {file: {library: {"best": {"variant", "us", "level"} or null, "best_any": {...}, "best_reused": {...} or
|
||||
null, "best_reused_any": {...} or null, "variants": {variant: {"us", "level"}}, "excluded": {...}}}}}` for the chart
|
||||
scripts (`best_reused`: the best full reused variant; `best_reused_any`: at any level). Several logs are combined by taking each cell's best
|
||||
time; a variant excluded for one file is left out for every file of that use case.
|
||||
On a shared machine, differences of a few percent are noise: run twice and compare.
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
# the Rust conformance run, one file per process; a file that aborts the process (stack overflow) is rerun one
|
||||
# variant per process, and a variant that aborts is printed as crashed
|
||||
B=$1; D=$2
|
||||
VARS=$($B --conformance $D 1 y_structure_lonely_int.json | sed -n 's/^conformance: [^|]* | \(.*\) | [a-z]*$/\1/p')
|
||||
for f in $(ls $D | grep '\.json$'); do
|
||||
out=$($B --conformance $D 1 "$f" 2>/dev/null)
|
||||
if [ $? = 0 ]; then echo "$out" | grep '^conformance:'; continue; fi
|
||||
while IFS= read -r v; do
|
||||
o=$(CONF_VARIANT="$v" $B --conformance $D 1 "$f" 2>/dev/null)
|
||||
if [ $? = 0 ]; then echo "$o" | grep '^conformance:'; else echo "conformance: $f | $v | crashed"; fi
|
||||
done <<< "$VARS"
|
||||
done
|
||||
echo "done: conformance"
|
||||
@@ -1,627 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||
|
||||
[[package]]
|
||||
name = "bench_rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"simd-json",
|
||||
"sonic-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826"
|
||||
|
||||
[[package]]
|
||||
name = "faststr"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ca7d44d22004409a61c393afb3369c8f7bb74abcae49fe249ee01dcc3002113"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"rkyv",
|
||||
"serde",
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "halfbrown"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c7ed2f2edad8a14c8186b847909a41fbb9c3eafa44f88bd891114ed5019da09"
|
||||
dependencies = [
|
||||
"hashbrown 0.16.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.17.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.191"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||
|
||||
[[package]]
|
||||
name = "munge"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c"
|
||||
dependencies = [
|
||||
"munge_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "munge_macro"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptr_meta"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743da816b98c921cdbe8628ef7381b76f25ecf4da599fc80aca90eae7ef70cc0"
|
||||
dependencies = [
|
||||
"ptr_meta_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptr_meta_derive"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c8d9ca532f185d5d4db7a7c9d51420b452168ea1c2b913953281bd6fe1fcbd0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rancor"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b534442d0fcdb55d66f373d9cac6d33b6293a2335bc2136dbd06ce0e87d2572"
|
||||
dependencies = [
|
||||
"ptr_meta",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3"
|
||||
dependencies = [
|
||||
"ref-cast-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast-impl"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rend"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "663ba70707f96e871406fe10d68128412e619b06d1d47cb91c3a4c6501176240"
|
||||
|
||||
[[package]]
|
||||
name = "rkyv"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9776093b7ca170454ab1406954f7b7d97a57c51dc6c0642957fb2ef25c2d399"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hashbrown 0.17.1",
|
||||
"indexmap",
|
||||
"munge",
|
||||
"ptr_meta",
|
||||
"rancor",
|
||||
"rend",
|
||||
"rkyv_derive",
|
||||
"tinyvec",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkyv_derive"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c25ef604ac7dd839d44d64648952ea23c97866f124ff671b0ed2cf3ad9bb06e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.154"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-json"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8f2e4d523646f7da6dde3983bd18ede0babc21c258ab708b3dd93ea0259719d"
|
||||
dependencies = [
|
||||
"halfbrown",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"simdutf8",
|
||||
"value-trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||
|
||||
[[package]]
|
||||
name = "sonic-number"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7c350a05f295f922fc153a3af8b443c10db70904a9291a624ddb6058c6110d0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sonic-rs"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "756586caeeb21126a57c17d1ef2b9386e2613ba784aae0f27104f5e9982335ec"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bumpalo",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"faststr",
|
||||
"itoa",
|
||||
"ref-cast",
|
||||
"serde",
|
||||
"simdutf8",
|
||||
"sonic-number",
|
||||
"sonic-simd",
|
||||
"thiserror",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sonic-simd"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f99e664ecd2d85a68c87e3c7a3cfe691f647ea9e835de984aba4d54a41f817d4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.119"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a0e2d11620c50695fe12bbbfde96b3477fe606e7284c22d505c12ce51214514"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-trait"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "545a3d7089f11f1741d12963c057adf9443fc24325110a6a6daf582e825fd51b"
|
||||
dependencies = [
|
||||
"float-cmp",
|
||||
"halfbrown",
|
||||
"itoa",
|
||||
"ryu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.4+wasi-0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.129"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.129"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.129"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.9",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.129"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5fe1f8f1b06191a00962174c61aa5005e0bb391a6d80d07e24d115c01a92ed8"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "863ad3ac83293fb4d740aedbfdc9240dd8d1a50c1099acd76ce80ce7c7230c7f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||
@@ -1,15 +0,0 @@
|
||||
[package]
|
||||
name = "bench_rs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
simd-json = "*"
|
||||
sonic-rs = "*"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { version = "*", features = ["float_roundtrip"] }
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
@@ -1,968 +0,0 @@
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||
// | | |__ | | | | | | version 3.12.0
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// The Rust counterpart of bench_all.cpp: the same use cases (validate, sum, select, edit, minify, write), files,
|
||||
// checks (right result; validation level from malformed-input probes) and timing method (every variant interleaved in every round, each
|
||||
// timed call after an untimed one, best round); see README.md. The input is the file as bytes (&[u8]); simd-json
|
||||
// parses in place, so its variants copy the input inside the timed call.
|
||||
//
|
||||
// Usage: bench_rs <json_test_data dir> [rounds] [document] [use case]
|
||||
use serde::de::{DeserializeOwned, DeserializeSeed, IgnoredAny, MapAccess, SeqAccess, Visitor};
|
||||
use simd_json::prelude::*;
|
||||
use sonic_rs::{JsonContainerTrait, JsonValueMutTrait, JsonValueTrait};
|
||||
use std::cell::RefCell;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
struct Stats {
|
||||
num: f64,
|
||||
str_: usize,
|
||||
nodes: usize,
|
||||
}
|
||||
|
||||
// ---- sum: walk a DOM, visit every value, convert every number, touch every string and key
|
||||
|
||||
fn walk_simd(v: &simd_json::BorrowedValue, st: &mut Stats) {
|
||||
st.nodes += 1;
|
||||
if let Some(o) = v.as_object() {
|
||||
for (k, x) in o.iter() {
|
||||
st.str_ += k.len();
|
||||
walk_simd(x, st);
|
||||
}
|
||||
} else if let Some(a) = v.as_array() {
|
||||
for x in a.iter() {
|
||||
walk_simd(x, st);
|
||||
}
|
||||
} else if let Some(s) = v.as_str() {
|
||||
st.str_ += s.len();
|
||||
} else if v.is_u64() {
|
||||
st.num += v.as_u64().unwrap() as f64;
|
||||
} else if v.is_i64() {
|
||||
st.num += v.as_i64().unwrap() as f64;
|
||||
} else if v.is_f64() {
|
||||
st.num += v.as_f64().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_sonic(v: &sonic_rs::Value, st: &mut Stats) {
|
||||
st.nodes += 1;
|
||||
if let Some(o) = v.as_object() {
|
||||
for (k, x) in o.iter() {
|
||||
st.str_ += k.len();
|
||||
walk_sonic(x, st);
|
||||
}
|
||||
} else if let Some(a) = v.as_array() {
|
||||
for x in a.iter() {
|
||||
walk_sonic(x, st);
|
||||
}
|
||||
} else if let Some(s) = v.as_str() {
|
||||
st.str_ += s.len();
|
||||
} else if v.is_number() {
|
||||
if let Some(u) = v.as_u64() {
|
||||
st.num += u as f64;
|
||||
} else if let Some(i) = v.as_i64() {
|
||||
st.num += i as f64;
|
||||
} else {
|
||||
st.num += v.as_f64().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_serde(v: &serde_json::Value, st: &mut Stats) {
|
||||
st.nodes += 1;
|
||||
match v {
|
||||
serde_json::Value::Object(o) => {
|
||||
for (k, x) in o.iter() {
|
||||
st.str_ += k.len();
|
||||
walk_serde(x, st);
|
||||
}
|
||||
}
|
||||
serde_json::Value::Array(a) => {
|
||||
for x in a.iter() {
|
||||
walk_serde(x, st);
|
||||
}
|
||||
}
|
||||
serde_json::Value::String(s) => st.str_ += s.len(),
|
||||
serde_json::Value::Number(n) => {
|
||||
if let Some(u) = n.as_u64() {
|
||||
st.num += u as f64;
|
||||
} else if let Some(i) = n.as_i64() {
|
||||
st.num += i as f64;
|
||||
} else {
|
||||
st.num += n.as_f64().unwrap();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// the same visit without a DOM: a serde visitor, driven by any serde deserializer, in document order
|
||||
struct Sum<'a>(&'a mut Stats);
|
||||
struct Key<'a>(&'a mut Stats);
|
||||
|
||||
impl<'de> DeserializeSeed<'de> for Sum<'_> {
|
||||
type Value = ();
|
||||
fn deserialize<D: serde::Deserializer<'de>>(self, d: D) -> Result<(), D::Error> {
|
||||
d.deserialize_any(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for Sum<'_> {
|
||||
type Value = ();
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.write_str("a JSON value")
|
||||
}
|
||||
fn visit_unit<E: serde::de::Error>(self) -> Result<(), E> {
|
||||
self.0.nodes += 1;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_bool<E: serde::de::Error>(self, _: bool) -> Result<(), E> {
|
||||
self.0.nodes += 1;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<(), E> {
|
||||
self.0.nodes += 1;
|
||||
self.0.num += v as f64;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<(), E> {
|
||||
self.0.nodes += 1;
|
||||
self.0.num += v as f64;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<(), E> {
|
||||
self.0.nodes += 1;
|
||||
self.0.num += v;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<(), E> {
|
||||
self.0.nodes += 1;
|
||||
self.0.str_ += v.len();
|
||||
Ok(())
|
||||
}
|
||||
fn visit_seq<A: SeqAccess<'de>>(self, mut a: A) -> Result<(), A::Error> {
|
||||
let st = self.0;
|
||||
st.nodes += 1;
|
||||
while a.next_element_seed(Sum(&mut *st))?.is_some() {}
|
||||
Ok(())
|
||||
}
|
||||
fn visit_map<A: MapAccess<'de>>(self, mut a: A) -> Result<(), A::Error> {
|
||||
let st = self.0;
|
||||
st.nodes += 1;
|
||||
while a.next_key_seed(Key(&mut *st))?.is_some() {
|
||||
a.next_value_seed(Sum(&mut *st))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> DeserializeSeed<'de> for Key<'_> {
|
||||
type Value = ();
|
||||
fn deserialize<D: serde::Deserializer<'de>>(self, d: D) -> Result<(), D::Error> {
|
||||
d.deserialize_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for Key<'_> {
|
||||
type Value = ();
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.write_str("a key")
|
||||
}
|
||||
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<(), E> {
|
||||
self.0.str_ += v.len();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn sum_serde(s: &[u8], st: &mut Stats) -> bool {
|
||||
let mut de = serde_json::Deserializer::from_slice(s);
|
||||
Sum(st).deserialize(&mut de).is_ok() && de.end().is_ok()
|
||||
}
|
||||
|
||||
fn sum_sonic(s: &[u8], st: &mut Stats) -> bool {
|
||||
let mut de = sonic_rs::Deserializer::from_slice(s);
|
||||
Sum(st).deserialize(&mut de).is_ok() && de.end().is_ok()
|
||||
}
|
||||
|
||||
fn sum_simd(s: &[u8], st: &mut Stats) -> bool {
|
||||
let mut b = s.to_vec();
|
||||
match simd_json::Deserializer::from_slice(&mut b) {
|
||||
Ok(mut de) => Sum(st).deserialize(&mut de).is_ok(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
// ---- select: read a few fields of every record (the fields of bench_view.cpp)
|
||||
|
||||
// on a DOM; serde_json's is the reference
|
||||
macro_rules! pick_value {
|
||||
($fname:ident, $t:ty) => {
|
||||
fn $fname(name: &str, r: &$t) -> f64 {
|
||||
fn size(v: &$t) -> usize {
|
||||
if let Some(a) = v.as_array() {
|
||||
a.len()
|
||||
} else {
|
||||
v.as_object().unwrap().len()
|
||||
}
|
||||
}
|
||||
fn status(acc: &mut f64, s: &$t) {
|
||||
*acc += s["id"].as_u64().unwrap() as f64;
|
||||
*acc += s["user"]["screen_name"].as_str().unwrap().len() as f64;
|
||||
*acc += s["retweet_count"].as_i64().unwrap() as f64;
|
||||
}
|
||||
let mut acc = 0.0;
|
||||
match name {
|
||||
"twitter" => {
|
||||
for s in r["statuses"].as_array().unwrap().iter() {
|
||||
status(&mut acc, s);
|
||||
}
|
||||
}
|
||||
"status" => status(&mut acc, r),
|
||||
"citm_catalog" => {
|
||||
for p in r["performances"].as_array().unwrap().iter() {
|
||||
acc += (p["id"].as_u64().unwrap() + p["eventId"].as_u64().unwrap() + size(&p["seatCategories"]) as u64) as f64;
|
||||
}
|
||||
acc += size(&r["events"]) as f64;
|
||||
}
|
||||
"canada" => {
|
||||
let g = &r["features"][0]["geometry"];
|
||||
acc += (r["type"].as_str().unwrap().len() + g["type"].as_str().unwrap().len() + size(&g["coordinates"])) as f64;
|
||||
}
|
||||
"jeopardy" => {
|
||||
for q in r.as_array().unwrap().iter() {
|
||||
acc += if q["round"].as_str().unwrap() == "Final Jeopardy!" { 1.0 } else { 0.0 };
|
||||
acc += q["category"].as_str().unwrap().len() as f64;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
acc
|
||||
}
|
||||
};
|
||||
}
|
||||
pick_value!(pick_serde, serde_json::Value);
|
||||
pick_value!(pick_sonic, sonic_rs::Value);
|
||||
pick_value!(pick_simd, simd_json::BorrowedValue<'_>);
|
||||
|
||||
// into structs that declare only the fields the selection uses, the same data as nlohmann/json's from_json() structs in
|
||||
// bench_all.cpp (nsel); unknown keys are skipped; Count counts the elements of an array or the members of an object
|
||||
// (nlohmann's count_only)
|
||||
mod sel {
|
||||
use serde::de::{Deserializer, IgnoredAny, MapAccess, SeqAccess, Visitor};
|
||||
use serde::Deserialize;
|
||||
use std::collections::BTreeMap;
|
||||
pub struct Count(pub usize);
|
||||
impl<'de> Deserialize<'de> for Count {
|
||||
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Count, D::Error> {
|
||||
struct V;
|
||||
impl<'de> Visitor<'de> for V {
|
||||
type Value = Count;
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.write_str("an array or an object")
|
||||
}
|
||||
fn visit_seq<A: SeqAccess<'de>>(self, mut a: A) -> Result<Count, A::Error> {
|
||||
let mut n = 0;
|
||||
while a.next_element::<IgnoredAny>()?.is_some() {
|
||||
n += 1;
|
||||
}
|
||||
Ok(Count(n))
|
||||
}
|
||||
fn visit_map<A: MapAccess<'de>>(self, mut a: A) -> Result<Count, A::Error> {
|
||||
let mut n = 0;
|
||||
while a.next_entry::<IgnoredAny, IgnoredAny>()?.is_some() {
|
||||
n += 1;
|
||||
}
|
||||
Ok(Count(n))
|
||||
}
|
||||
}
|
||||
d.deserialize_any(V)
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct User {
|
||||
pub screen_name: String,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Status {
|
||||
pub id: u64,
|
||||
pub user: User,
|
||||
pub retweet_count: i64,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Twitter {
|
||||
pub statuses: Vec<Status>,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Performance {
|
||||
pub id: u64,
|
||||
#[serde(rename = "eventId")]
|
||||
pub event_id: u64,
|
||||
#[serde(rename = "seatCategories")]
|
||||
pub seat_categories: Count,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Citm {
|
||||
pub events: BTreeMap<String, Count>,
|
||||
pub performances: Vec<Performance>,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Geometry {
|
||||
#[serde(rename = "type")]
|
||||
pub type_: String,
|
||||
pub coordinates: Count,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Feature {
|
||||
pub geometry: Geometry,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Canada {
|
||||
#[serde(rename = "type")]
|
||||
pub type_: String,
|
||||
pub features: Vec<Feature>,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Question {
|
||||
pub category: String,
|
||||
pub round: String,
|
||||
}
|
||||
}
|
||||
|
||||
trait De {
|
||||
fn de<T: DeserializeOwned>(s: &[u8]) -> Option<T>;
|
||||
}
|
||||
struct SerdeJson;
|
||||
struct SerdeJsonStr; // checks UTF-8 with std::str::from_utf8 first, then reads from the &str
|
||||
struct SonicRs;
|
||||
struct SimdJson;
|
||||
impl De for SerdeJson {
|
||||
fn de<T: DeserializeOwned>(s: &[u8]) -> Option<T> {
|
||||
serde_json::from_slice(s).ok()
|
||||
}
|
||||
}
|
||||
impl De for SerdeJsonStr {
|
||||
fn de<T: DeserializeOwned>(s: &[u8]) -> Option<T> {
|
||||
serde_json::from_str(std::str::from_utf8(s).ok()?).ok()
|
||||
}
|
||||
}
|
||||
impl De for SonicRs {
|
||||
fn de<T: DeserializeOwned>(s: &[u8]) -> Option<T> {
|
||||
sonic_rs::from_slice(s).ok()
|
||||
}
|
||||
}
|
||||
impl De for SimdJson {
|
||||
fn de<T: DeserializeOwned>(s: &[u8]) -> Option<T> {
|
||||
let mut b = s.to_vec();
|
||||
simd_json::serde::from_slice(&mut b).ok()
|
||||
}
|
||||
}
|
||||
|
||||
fn pick_structs<D: De>(name: &str, s: &[u8]) -> Option<f64> {
|
||||
fn status(acc: &mut f64, x: &sel::Status) {
|
||||
*acc += x.id as f64;
|
||||
*acc += x.user.screen_name.len() as f64;
|
||||
*acc += x.retweet_count as f64;
|
||||
}
|
||||
let mut acc = 0.0;
|
||||
match name {
|
||||
"twitter" => {
|
||||
let t: sel::Twitter = D::de(s)?;
|
||||
for x in &t.statuses {
|
||||
status(&mut acc, x);
|
||||
}
|
||||
}
|
||||
"status" => {
|
||||
let x: sel::Status = D::de(s)?;
|
||||
status(&mut acc, &x);
|
||||
}
|
||||
"citm_catalog" => {
|
||||
let c: sel::Citm = D::de(s)?;
|
||||
for p in &c.performances {
|
||||
acc += (p.id + p.event_id + p.seat_categories.0 as u64) as f64;
|
||||
}
|
||||
acc += c.events.len() as f64;
|
||||
}
|
||||
"canada" => {
|
||||
let c: sel::Canada = D::de(s)?;
|
||||
let g = &c.features[0].geometry;
|
||||
acc += (c.type_.len() + g.type_.len() + g.coordinates.0) as f64;
|
||||
}
|
||||
"jeopardy" => {
|
||||
let q: Vec<sel::Question> = D::de(s)?;
|
||||
for x in &q {
|
||||
acc += if x.round == "Final Jeopardy!" { 1.0 } else { 0.0 };
|
||||
acc += x.category.len() as f64;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Some(acc)
|
||||
}
|
||||
|
||||
// ---- edit: the same edits as bench_all.cpp, then write compact JSON
|
||||
|
||||
fn edit_serde(name: &str, r: &mut serde_json::Value) {
|
||||
fn status(s: &mut serde_json::Value) {
|
||||
let o = s.as_object_mut().unwrap();
|
||||
let rc = o["retweet_count"].as_i64().unwrap();
|
||||
o.insert("retweet_count".to_string(), (rc + 1).into());
|
||||
o.remove("entities");
|
||||
o.insert("seen".to_string(), true.into());
|
||||
}
|
||||
match name {
|
||||
"twitter" => {
|
||||
for s in r["statuses"].as_array_mut().unwrap() {
|
||||
status(s);
|
||||
}
|
||||
}
|
||||
"status" => status(r),
|
||||
"citm_catalog" => {
|
||||
for p in r["performances"].as_array_mut().unwrap() {
|
||||
let o = p.as_object_mut().unwrap();
|
||||
let start = o["start"].as_i64().unwrap();
|
||||
o.insert("start".to_string(), (start + 1).into());
|
||||
o.remove("seatMapImage");
|
||||
o.insert("seen".to_string(), true.into());
|
||||
}
|
||||
}
|
||||
"canada" => {
|
||||
r["features"][0]["properties"]["name"] = "Kanada".into();
|
||||
for f in r["features"].as_array_mut().unwrap() {
|
||||
f["geometry"]["coordinates"][0].as_array_mut().unwrap().push(serde_json::json!([0.5, 0.25]));
|
||||
}
|
||||
}
|
||||
"jeopardy" => {
|
||||
for q in r.as_array_mut().unwrap() {
|
||||
let o = q.as_object_mut().unwrap();
|
||||
o.insert("value".to_string(), serde_json::Value::Null);
|
||||
o.remove("air_date");
|
||||
o.insert("seen".to_string(), true.into());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn edit_sonic(name: &str, r: &mut sonic_rs::Value) {
|
||||
fn status(s: &mut sonic_rs::Value) {
|
||||
let o = s.as_object_mut().unwrap();
|
||||
let rc = o.get(&"retweet_count").unwrap().as_i64().unwrap();
|
||||
o.insert("retweet_count", rc + 1);
|
||||
o.remove(&"entities");
|
||||
o.insert("seen", true);
|
||||
}
|
||||
match name {
|
||||
"twitter" => {
|
||||
for s in r.get_mut("statuses").unwrap().as_array_mut().unwrap().iter_mut() {
|
||||
status(s);
|
||||
}
|
||||
}
|
||||
"status" => status(r),
|
||||
"citm_catalog" => {
|
||||
for p in r.get_mut("performances").unwrap().as_array_mut().unwrap().iter_mut() {
|
||||
let o = p.as_object_mut().unwrap();
|
||||
let start = o.get(&"start").unwrap().as_i64().unwrap();
|
||||
o.insert("start", start + 1);
|
||||
o.remove(&"seatMapImage");
|
||||
o.insert("seen", true);
|
||||
}
|
||||
}
|
||||
"canada" => {
|
||||
let fs = r.get_mut("features").unwrap().as_array_mut().unwrap();
|
||||
fs[0].get_mut("properties").unwrap().as_object_mut().unwrap().insert("name", "Kanada");
|
||||
for f in fs.iter_mut() {
|
||||
let ring = f.get_mut("geometry").unwrap().get_mut("coordinates").unwrap().get_mut(0).unwrap();
|
||||
ring.as_array_mut().unwrap().push(sonic_rs::json!([0.5, 0.25]));
|
||||
}
|
||||
}
|
||||
"jeopardy" => {
|
||||
for q in r.as_array_mut().unwrap().iter_mut() {
|
||||
let o = q.as_object_mut().unwrap();
|
||||
o.insert("value", sonic_rs::Value::new_null());
|
||||
o.remove(&"air_date");
|
||||
o.insert("seen", true);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! edit_simd {
|
||||
($fname:ident, $t:ty) => {
|
||||
fn $fname(name: &str, r: &mut $t) {
|
||||
fn status(s: &mut $t) {
|
||||
let o = s.as_object_mut().unwrap();
|
||||
let rc = o.get("retweet_count").unwrap().as_i64().unwrap();
|
||||
o.insert("retweet_count".into(), (rc + 1).into());
|
||||
o.remove("entities");
|
||||
o.insert("seen".into(), true.into());
|
||||
}
|
||||
match name {
|
||||
"twitter" => {
|
||||
for s in r.as_object_mut().unwrap().get_mut("statuses").unwrap().as_array_mut().unwrap().iter_mut() {
|
||||
status(s);
|
||||
}
|
||||
}
|
||||
"status" => status(r),
|
||||
"citm_catalog" => {
|
||||
for p in r.as_object_mut().unwrap().get_mut("performances").unwrap().as_array_mut().unwrap().iter_mut() {
|
||||
let o = p.as_object_mut().unwrap();
|
||||
let start = o.get("start").unwrap().as_i64().unwrap();
|
||||
o.insert("start".into(), (start + 1).into());
|
||||
o.remove("seatMapImage");
|
||||
o.insert("seen".into(), true.into());
|
||||
}
|
||||
}
|
||||
"canada" => {
|
||||
let fs = r.as_object_mut().unwrap().get_mut("features").unwrap().as_array_mut().unwrap();
|
||||
fs[0].as_object_mut().unwrap().get_mut("properties").unwrap().as_object_mut().unwrap().insert("name".into(), "Kanada".into());
|
||||
for f in fs.iter_mut() {
|
||||
let g = f.as_object_mut().unwrap().get_mut("geometry").unwrap().as_object_mut().unwrap();
|
||||
let ring = &mut g.get_mut("coordinates").unwrap().as_array_mut().unwrap()[0];
|
||||
ring.as_array_mut().unwrap().push(vec![<$t>::from(0.5), <$t>::from(0.25)].into());
|
||||
}
|
||||
}
|
||||
"jeopardy" => {
|
||||
for q in r.as_array_mut().unwrap().iter_mut() {
|
||||
let o = q.as_object_mut().unwrap();
|
||||
o.insert("value".into(), <$t>::Static(simd_json::StaticNode::Null));
|
||||
o.remove("air_date");
|
||||
o.insert("seen".into(), true.into());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
edit_simd!(edit_simd_owned, simd_json::OwnedValue);
|
||||
edit_simd!(edit_simd_borrowed, simd_json::BorrowedValue<'_>);
|
||||
|
||||
// ---- driver
|
||||
|
||||
struct Res {
|
||||
st: Stats,
|
||||
acc: f64,
|
||||
want: bool,
|
||||
out: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Res {
|
||||
fn new(want: bool) -> Res {
|
||||
Res { st: Stats::default(), acc: 0.0, want, out: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
fn emit(r: &mut Res, o: Vec<u8>) -> bool {
|
||||
r.acc = o.len() as f64;
|
||||
if r.want {
|
||||
r.out = o;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
struct Variant<'a> {
|
||||
name: &'static str,
|
||||
f: Box<dyn Fn(&[u8], &mut Res) -> bool + 'a>,
|
||||
any_order: bool, // sum: visits objects in another order than the document's
|
||||
}
|
||||
|
||||
fn v<'a>(name: &'static str, f: impl Fn(&[u8], &mut Res) -> bool + 'a) -> Variant<'a> {
|
||||
Variant { name, f: Box::new(f), any_order: false }
|
||||
}
|
||||
|
||||
fn v_any<'a>(name: &'static str, f: impl Fn(&[u8], &mut Res) -> bool + 'a) -> Variant<'a> {
|
||||
Variant { name, f: Box::new(f), any_order: true }
|
||||
}
|
||||
|
||||
fn run(var: &Variant, s: &[u8], r: &mut Res) -> bool {
|
||||
catch_unwind(AssertUnwindSafe(|| (var.f)(s, r))).unwrap_or(false)
|
||||
}
|
||||
|
||||
static mut SINK: f64 = 0.0;
|
||||
fn sink(x: f64) {
|
||||
unsafe { std::ptr::write_volatile(std::ptr::addr_of_mut!(SINK), x) }
|
||||
}
|
||||
|
||||
// the input contract of bench_all.cpp: at least 64 bytes of spare capacity
|
||||
fn padded(s: &[u8]) -> Vec<u8> {
|
||||
let mut r = Vec::with_capacity(s.len() + 64);
|
||||
r.extend_from_slice(s);
|
||||
r
|
||||
}
|
||||
|
||||
// the minified inputs (twitter_min, citm_catalog_min): the whitespace outside strings removed, the bytes inside strings
|
||||
// untouched (the same function as strip_ws in bench_all.cpp)
|
||||
fn strip_ws(s: &[u8]) -> Vec<u8> {
|
||||
let mut r = Vec::with_capacity(s.len());
|
||||
let mut in_string = false;
|
||||
let mut i = 0;
|
||||
while i < s.len() {
|
||||
let ch = s[i];
|
||||
if in_string {
|
||||
r.push(ch);
|
||||
if ch == b'\\' && i + 1 < s.len() {
|
||||
i += 1;
|
||||
r.push(s[i]);
|
||||
} else if ch == b'"' {
|
||||
in_string = false;
|
||||
}
|
||||
} else if ch != b' ' && ch != b'\n' && ch != b'\r' && ch != b'\t' {
|
||||
r.push(ch);
|
||||
in_string = ch == b'"';
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
// malformed inputs derived from a valid document, as in bench_all.cpp (0xFF in a string value, not a key)
|
||||
// (what, text, is the 0xFF probe)
|
||||
fn malformed(s: &[u8]) -> Vec<(&'static str, Vec<u8>, bool)> {
|
||||
let (mut first_close, mut mid_quote, mut last_quote) = (None, None, None);
|
||||
let mut in_string = false;
|
||||
let mut stack: Vec<u8> = Vec::new();
|
||||
let mut prev = 0u8;
|
||||
let mut i = 0;
|
||||
while i < s.len() {
|
||||
let ch = s[i];
|
||||
if in_string {
|
||||
if ch == b'\\' {
|
||||
i += 1;
|
||||
} else if ch == b'"' {
|
||||
in_string = false;
|
||||
}
|
||||
} else if ch == b'"' {
|
||||
in_string = true;
|
||||
let value = prev == b':' || (stack.last() == Some(&b'[') && (prev == b'[' || prev == b','));
|
||||
if value {
|
||||
last_quote = Some(i);
|
||||
if mid_quote.is_none() && i >= s.len() / 2 {
|
||||
mid_quote = Some(i);
|
||||
}
|
||||
}
|
||||
prev = b'"';
|
||||
} else if ch == b'{' || ch == b'[' {
|
||||
stack.push(ch);
|
||||
prev = ch;
|
||||
} else if ch == b'}' || ch == b']' {
|
||||
if ch == b'}' && first_close.is_none() {
|
||||
first_close = Some(i);
|
||||
}
|
||||
stack.pop();
|
||||
prev = ch;
|
||||
} else if ch == b':' || ch == b',' {
|
||||
prev = ch;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
let mut t = s.to_vec();
|
||||
while matches!(t.last(), Some(b' ' | b'\n' | b'\r' | b'\t')) {
|
||||
t.pop();
|
||||
}
|
||||
let mut trailing = t.clone();
|
||||
trailing.extend_from_slice(b" ]x"); // after the value
|
||||
t.pop();
|
||||
let mut out = vec![("truncated input", padded(&t), false), ("trailing garbage", padded(&trailing), false)];
|
||||
let mut t = s.to_vec();
|
||||
if let Some(c) = first_close {
|
||||
t.insert(c, b',');
|
||||
out.push(("a stray comma before '}'", padded(&t), false));
|
||||
} else {
|
||||
// a file without objects (--files): the comma goes before the last ']'
|
||||
let c = (0..t.len()).rev().find(|&i| t[i] == b']').unwrap();
|
||||
t.insert(c, b',');
|
||||
out.push(("a stray comma before ']'", padded(&t), false));
|
||||
}
|
||||
// a file without string values (--files) gets no UTF-8 probe
|
||||
if let Some(q) = mid_quote.or(last_quote) {
|
||||
let mut t = s.to_vec();
|
||||
t.insert(q + 1, 0xFF);
|
||||
out.push(("invalid UTF-8 (0xFF in a string)", padded(&t), true));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn same_text(out: &[u8], expected: &serde_json::Value) -> bool {
|
||||
serde_json::from_slice::<serde_json::Value>(out).map(|v| v == *expected).unwrap_or(false)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
// --files <dir>: every *.json file of the directory instead of the files below, without select and edit;
|
||||
// --conformance <dir>: every validate variant on every *.json file of the directory (JSONTestSuite), no timing
|
||||
let files = args.len() > 1 && args[1] == "--files";
|
||||
let conformance = args.len() > 1 && args[1] == "--conformance";
|
||||
let a = if files || conformance { 2 } else { 1 };
|
||||
if args.len() <= a {
|
||||
eprintln!("usage: {0} <json_test_data dir> [rounds] [document] [use case]\n {0} --files <dir> [rounds] [document] [use case]\n {0} --conformance <dir>", args[0]);
|
||||
std::process::exit(1);
|
||||
}
|
||||
let t = format!("{}/", args[a]);
|
||||
let rounds: usize = args.get(a + 1).map(|r| r.parse().unwrap()).unwrap_or(30).max(1);
|
||||
let only: String = args.get(a + 2).cloned().unwrap_or_default();
|
||||
let only_uc: String = if conformance { "validate".to_string() } else { args.get(a + 3).cloned().unwrap_or_default() };
|
||||
// (file, text, batch, the document whose select and edit apply)
|
||||
let mut docs: Vec<(String, Vec<u8>, usize, String)> = Vec::new();
|
||||
if files || conformance {
|
||||
let mut paths: Vec<std::path::PathBuf> = std::fs::read_dir(&t).unwrap().map(|e| e.unwrap().path()).filter(|p| p.extension().map_or(false, |x| x == "json")).collect();
|
||||
paths.sort();
|
||||
for p in paths {
|
||||
// small files are timed in batches of about 500 KB of input, as status is
|
||||
let text = padded(&std::fs::read(&p).unwrap());
|
||||
let name = if conformance { p.file_name() } else { p.file_stem() }.unwrap().to_string_lossy().to_string();
|
||||
let batch = (500000 / text.len().max(1)).max(1);
|
||||
docs.push((name.clone(), text, batch, name));
|
||||
}
|
||||
} else {
|
||||
for f in ["nativejson-benchmark/twitter.json", "nativejson-benchmark/citm_catalog.json", "nativejson-benchmark/canada.json", "jeopardy/jeopardy.json"] {
|
||||
let name = f.split('/').nth(1).unwrap().trim_end_matches(".json").to_string();
|
||||
docs.push((name.clone(), padded(&std::fs::read(format!("{}{}", t, f)).unwrap()), 1, name));
|
||||
}
|
||||
let tw: serde_json::Value = serde_json::from_slice(&docs[0].1).unwrap();
|
||||
docs.push(("status".to_string(), padded(serde_json::to_string(&tw["statuses"][0]).unwrap().as_bytes()), 200, "status".to_string()));
|
||||
let (tw_min, citm_min) = (padded(&strip_ws(&docs[0].1)), padded(&strip_ws(&docs[1].1)));
|
||||
docs.push(("twitter_min".to_string(), tw_min, 1, "twitter".to_string()));
|
||||
docs.push(("citm_catalog_min".to_string(), citm_min, 1, "citm_catalog".to_string()));
|
||||
}
|
||||
|
||||
std::panic::set_hook(Box::new(|_| {})); // a panic is a failed call, reported by the checks
|
||||
let simd_reused = RefCell::new((simd_json::Buffers::default(), Vec::<u8>::new()));
|
||||
let mut excluded_total = 0;
|
||||
for (file, s, batch, base) in &docs {
|
||||
if !only.is_empty() && *file != only {
|
||||
continue;
|
||||
}
|
||||
let (file, name) = (file.as_str(), base.as_str());
|
||||
let s = s.as_slice();
|
||||
let bad = if conformance { Vec::new() } else { malformed(s) };
|
||||
for uc in ["validate", "sum", "select", "edit", "minify", "write"] {
|
||||
if (!only_uc.is_empty() && uc != only_uc) || (files && (uc == "select" || uc == "edit")) {
|
||||
continue;
|
||||
}
|
||||
// write: each library's document, parsed once outside the timer
|
||||
let mut wbuf: Vec<u8>;
|
||||
let (w_serde, w_sonic, w_simd) = if uc == "write" {
|
||||
wbuf = s.to_vec();
|
||||
(
|
||||
Some(serde_json::from_slice::<serde_json::Value>(s).unwrap()),
|
||||
Some(sonic_rs::from_slice::<sonic_rs::Value>(s).unwrap()),
|
||||
Some(simd_json::to_borrowed_value(&mut wbuf).unwrap()),
|
||||
)
|
||||
} else {
|
||||
(None, None, None)
|
||||
};
|
||||
let reuse = &simd_reused;
|
||||
let all: Vec<Variant> = match uc {
|
||||
"validate" => vec![
|
||||
v("serde_json: IgnoredAny", |s, _| serde_json::from_slice::<IgnoredAny>(s).is_ok()),
|
||||
v("serde_json: from_utf8 + IgnoredAny", |s, _| std::str::from_utf8(s).ok().map_or(false, |t| serde_json::from_str::<IgnoredAny>(t).is_ok())),
|
||||
v("serde_json: Value", |s, _| serde_json::from_slice::<serde_json::Value>(s).is_ok()),
|
||||
v("sonic-rs: IgnoredAny", |s, _| sonic_rs::from_slice::<IgnoredAny>(s).is_ok()),
|
||||
v("sonic-rs: Value", |s, _| sonic_rs::from_slice::<sonic_rs::Value>(s).is_ok()),
|
||||
v("simd-json: tape (copy)", |s, _| { let mut b = s.to_vec(); simd_json::to_tape(&mut b).is_ok() }),
|
||||
v("simd-json: borrowed (copy)", |s, _| { let mut b = s.to_vec(); let ok = simd_json::to_borrowed_value(&mut b).is_ok(); ok }),
|
||||
v("simd-json: tape (reused)", move |s, _| {
|
||||
let mut g = reuse.borrow_mut();
|
||||
let (ref mut bufs, ref mut b) = *g;
|
||||
b.clear();
|
||||
b.extend_from_slice(s);
|
||||
simd_json::to_tape_with_buffers(b, bufs).is_ok()
|
||||
}),
|
||||
],
|
||||
"sum" => vec![
|
||||
v("serde_json: visitor", |s, r| sum_serde(s, &mut r.st)),
|
||||
v_any("serde_json: Value", |s, r| serde_json::from_slice::<serde_json::Value>(s).map(|x| walk_serde(&x, &mut r.st)).is_ok()),
|
||||
v("sonic-rs: visitor", |s, r| sum_sonic(s, &mut r.st)),
|
||||
v("sonic-rs: Value", |s, r| sonic_rs::from_slice::<sonic_rs::Value>(s).map(|x| walk_sonic(&x, &mut r.st)).is_ok()),
|
||||
v("simd-json: visitor (copy)", |s, r| sum_simd(s, &mut r.st)),
|
||||
v_any("simd-json: borrowed (copy)", |s, r| { let mut b = s.to_vec(); simd_json::to_borrowed_value(&mut b).map(|x| walk_simd(&x, &mut r.st)).is_ok() }),
|
||||
v_any("simd-json: borrowed (reused)", move |s, r| {
|
||||
let mut g = reuse.borrow_mut();
|
||||
let (ref mut bufs, ref mut b) = *g;
|
||||
b.clear();
|
||||
b.extend_from_slice(s);
|
||||
simd_json::to_borrowed_value_with_buffers(b, bufs).map(|x| walk_simd(&x, &mut r.st)).is_ok()
|
||||
}),
|
||||
],
|
||||
"select" => vec![
|
||||
v("serde_json: structs", move |s, r| pick_structs::<SerdeJson>(name, s).map(|a| r.acc = a).is_some()),
|
||||
v("serde_json: from_utf8 + structs", move |s, r| pick_structs::<SerdeJsonStr>(name, s).map(|a| r.acc = a).is_some()),
|
||||
v("serde_json: Value", move |s, r| serde_json::from_slice::<serde_json::Value>(s).map(|x| r.acc = pick_serde(name, &x)).is_ok()),
|
||||
v("sonic-rs: structs", move |s, r| pick_structs::<SonicRs>(name, s).map(|a| r.acc = a).is_some()),
|
||||
v("sonic-rs: Value", move |s, r| sonic_rs::from_slice::<sonic_rs::Value>(s).map(|x| r.acc = pick_sonic(name, &x)).is_ok()),
|
||||
v("simd-json: structs (copy)", move |s, r| pick_structs::<SimdJson>(name, s).map(|a| r.acc = a).is_some()),
|
||||
v("simd-json: borrowed (copy)", move |s, r| { let mut b = s.to_vec(); let ok = simd_json::to_borrowed_value(&mut b).map(|x| r.acc = pick_simd(name, &x)).is_ok(); ok }),
|
||||
],
|
||||
"edit" => vec![
|
||||
v("serde_json: Value", move |s, r| match serde_json::from_slice::<serde_json::Value>(s) {
|
||||
Ok(mut x) => { edit_serde(name, &mut x); emit(r, serde_json::to_vec(&x).unwrap()) }
|
||||
Err(_) => false,
|
||||
}),
|
||||
v("sonic-rs: Value", move |s, r| match sonic_rs::from_slice::<sonic_rs::Value>(s) {
|
||||
Ok(mut x) => { edit_sonic(name, &mut x); emit(r, sonic_rs::to_vec(&x).unwrap()) }
|
||||
Err(_) => false,
|
||||
}),
|
||||
v("simd-json: owned (copy)", move |s, r| { let mut b = s.to_vec(); match simd_json::to_owned_value(&mut b) {
|
||||
Ok(mut x) => { edit_simd_owned(name, &mut x); emit(r, simd_json::to_vec(&x).unwrap()) }
|
||||
Err(_) => false,
|
||||
}}),
|
||||
v("simd-json: borrowed (copy)", move |s, r| { let mut b = s.to_vec(); let ok = match simd_json::to_borrowed_value(&mut b) {
|
||||
Ok(mut x) => { edit_simd_borrowed(name, &mut x); emit(r, simd_json::to_vec(&x).unwrap()) }
|
||||
Err(_) => false,
|
||||
}; ok }),
|
||||
],
|
||||
"minify" => vec![
|
||||
v("serde_json: Value", |s, r| serde_json::from_slice::<serde_json::Value>(s).map(|x| emit(r, serde_json::to_vec(&x).unwrap())).unwrap_or(false)),
|
||||
v("sonic-rs: Value", |s, r| sonic_rs::from_slice::<sonic_rs::Value>(s).map(|x| emit(r, sonic_rs::to_vec(&x).unwrap())).unwrap_or(false)),
|
||||
v("simd-json: borrowed (copy)", |s, r| { let mut b = s.to_vec(); simd_json::to_borrowed_value(&mut b).map(|x| emit(r, simd_json::to_vec(&x).unwrap())).unwrap_or(false) }),
|
||||
],
|
||||
_ => {
|
||||
let (a, b, c) = (w_serde.as_ref().unwrap(), w_sonic.as_ref().unwrap(), w_simd.as_ref().unwrap());
|
||||
vec![
|
||||
v("serde_json: Value", move |_, r| emit(r, serde_json::to_vec(a).unwrap())),
|
||||
v("sonic-rs: Value", move |_, r| emit(r, sonic_rs::to_vec(b).unwrap())),
|
||||
v("simd-json: borrowed", move |_, r| emit(r, simd_json::to_vec(c).unwrap())),
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// the reference result: serde_json's visitor (sum, document order), Value (select, edit, minify, write)
|
||||
let mut ref_st = Stats::default();
|
||||
let mut ref_acc = 0.0;
|
||||
let mut ref_json = serde_json::Value::Null;
|
||||
match uc {
|
||||
"sum" => {
|
||||
sum_serde(s, &mut ref_st);
|
||||
println!("check {:<13} {:<9} reference: nodes {} str {} num {:.16e}", file, uc, ref_st.nodes, ref_st.str_, ref_st.num);
|
||||
}
|
||||
"select" => {
|
||||
ref_acc = pick_serde(name, &serde_json::from_slice(s).unwrap());
|
||||
println!("check {:<13} {:<9} reference: {:.16e}", file, uc, ref_acc);
|
||||
}
|
||||
"validate" => {}
|
||||
_ => {
|
||||
ref_json = serde_json::from_slice(s).unwrap();
|
||||
if uc == "edit" {
|
||||
edit_serde(name, &mut ref_json);
|
||||
}
|
||||
}
|
||||
}
|
||||
if conformance {
|
||||
// CONF_VARIANT=<name>: only this variant (a stack overflow aborts the process, see conformance.sh)
|
||||
let only_var = std::env::var("CONF_VARIANT").unwrap_or_default();
|
||||
for var in all.iter().filter(|v| only_var.is_empty() || v.name == only_var) {
|
||||
let mut r = Res::new(true);
|
||||
let verdict = match catch_unwind(AssertUnwindSafe(|| (var.f)(s, &mut r))) {
|
||||
Ok(true) => "accepted",
|
||||
Ok(false) => "rejected",
|
||||
Err(_) => "crashed",
|
||||
};
|
||||
println!("conformance: {} | {} | {}", file, var.name, verdict);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let n_all = all.len();
|
||||
let mut vs: Vec<Variant> = Vec::new();
|
||||
let mut levels: Vec<&str> = Vec::new();
|
||||
for var in all {
|
||||
let mut r = Res::new(true);
|
||||
let mut why = String::new();
|
||||
let mut panicked = false;
|
||||
if !catch_unwind(AssertUnwindSafe(|| (var.f)(s, &mut r))).unwrap_or_else(|_| {
|
||||
panicked = true;
|
||||
false
|
||||
}) {
|
||||
why = if panicked { "crashes on the valid input" } else { "rejects the valid input" }.to_string();
|
||||
} else if uc == "sum"
|
||||
&& !(r.st.nodes == ref_st.nodes
|
||||
&& r.st.str_ == ref_st.str_
|
||||
&& if var.any_order { (r.st.num - ref_st.num).abs() <= 1e-9 * ref_st.num.abs() } else { r.st.num == ref_st.num })
|
||||
{
|
||||
why = format!("wrong result (nodes {} str {} num {:.16e})", r.st.nodes, r.st.str_, r.st.num);
|
||||
} else if uc == "select" && r.acc != ref_acc {
|
||||
why = format!("wrong result ({:.16e})", r.acc);
|
||||
} else if (uc == "edit" || uc == "minify" || uc == "write") && !same_text(&r.out, &ref_json) {
|
||||
why = "the output does not read back as the expected document".to_string();
|
||||
}
|
||||
if why.is_empty() {
|
||||
// the validation level from the malformed-input probes, as in bench_all.cpp
|
||||
let mut level = "n/a";
|
||||
if uc != "write" {
|
||||
let (mut structural, mut utf8) = (false, false);
|
||||
let mut notes: Vec<String> = Vec::new();
|
||||
for (what, b, is_utf8) in &bad {
|
||||
let mut rb = Res::new(true);
|
||||
match catch_unwind(AssertUnwindSafe(|| (var.f)(b, &mut rb))) {
|
||||
Ok(false) => continue,
|
||||
Ok(true) => {
|
||||
notes.push(format!("accepts {}", what));
|
||||
if *is_utf8 { utf8 = true } else { structural = true }
|
||||
}
|
||||
Err(_) => {
|
||||
notes.push(format!("crashes on {}", what));
|
||||
structural = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
level = if structural { "partial" } else if utf8 { "no UTF-8" } else { "full" };
|
||||
if !notes.is_empty() {
|
||||
println!("level: {} {} | {} | {} | {}", file, uc, var.name, level, notes.join("; "));
|
||||
}
|
||||
}
|
||||
vs.push(var);
|
||||
levels.push(level);
|
||||
} else {
|
||||
excluded_total += 1;
|
||||
println!("excluded: {} {} | {} | {}", file, uc, var.name, why);
|
||||
}
|
||||
}
|
||||
println!("check {:<13} {:<9} {} of {} variants give the right result", file, uc, vs.len(), n_all);
|
||||
if vs.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let r = if s.len() > 10_000_000 { rounds.min((rounds / 5).max(3)) } else { rounds };
|
||||
let mut best = vec![f64::MAX; vs.len()];
|
||||
// a new order of the variants in every round (as in bench_all.cpp): a Fisher-Yates shuffle with xorshift64
|
||||
let mut order: Vec<usize> = (0..vs.len()).collect();
|
||||
let mut rng: u64 = 12345;
|
||||
for i in 0..r {
|
||||
if i > 0 {
|
||||
for j in (1..order.len()).rev() {
|
||||
rng ^= rng << 13;
|
||||
rng ^= rng >> 7;
|
||||
rng ^= rng << 17;
|
||||
order.swap(j, (rng % (j as u64 + 1)) as usize);
|
||||
}
|
||||
}
|
||||
for &k in &order {
|
||||
let var = &vs[k];
|
||||
let mut res = Res::new(false);
|
||||
run(var, s, &mut res); // untimed: the previous variant's leftovers are cleaned up here
|
||||
sink(res.st.num + res.acc);
|
||||
let t0 = Instant::now();
|
||||
for _ in 0..*batch {
|
||||
let mut rt = Res::new(false);
|
||||
let ok = run(var, s, &mut rt);
|
||||
sink(if ok { rt.st.num + rt.acc } else { -1.0 });
|
||||
}
|
||||
let ns = t0.elapsed().as_nanos() as f64 / *batch as f64;
|
||||
best[k] = best[k].min(ns);
|
||||
}
|
||||
}
|
||||
print!("{:<13} {:<9}", file, uc);
|
||||
for (k, var) in vs.iter().enumerate() {
|
||||
print!(" | {} [{}] {:.1}us ({:.2}x)", var.name, levels[k], best[k] / 1e3, best[k] / best[0]);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
println!("done: {} variant(s) excluded", excluded_total);
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# __ _____ _____ _____
|
||||
# __| | __| | | | JSON for Modern C++ (supporting code)
|
||||
# | | |__ | | | | | | version 3.12.0
|
||||
# |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Summarize runs of bench_all and bench_rs by use case.
|
||||
|
||||
Usage: summarize.py LOG... [--rust LOG...] [--json OUT.json]
|
||||
|
||||
Every variant carries a validation level from the malformed-input probes: "full" (rejects truncated input, a stray
|
||||
comma and invalid UTF-8), "no UTF-8" (accepts only the invalid UTF-8), "partial" (accepts or crashes on a structural
|
||||
error, or crashes on any probe), or "n/a" (write: no input to validate; counts as full). A variant's level is the
|
||||
worst it got for any file. Prints, for every use case and file,
|
||||
(a) per library the best "full" variant and, if faster, the best variant at any level, with their ratios to the
|
||||
best "full" nlohmann json_document variant (variants named "(reused)" or "(reused allocator)" keep a parser,
|
||||
document or allocator across calls and are never chosen as a library's best; neither are "(copy untimed)"
|
||||
variants, which copy their input before the timer starts), and in a "reused:" line the library's best reused
|
||||
variant in the same way,
|
||||
(b) all variants with their levels and times,
|
||||
(c) the variants below "full" with what the probes found, and the variants excluded for wrong results.
|
||||
--json writes {use case: {file: {library: {"best": {"variant", "us", "level"} or null, "best_any": {...},
|
||||
"best_reused": {...} or null, "best_reused_any": {...} or null, "variants": {variant: {"us", "level"}}, "excluded":
|
||||
{variant: reason}}}}} for the chart scripts ("best_reused" is the best full reused variant, "best_reused_any" the best
|
||||
reused variant at any level); variant names there omit the "<library>: " prefix.
|
||||
|
||||
Several logs are combined by taking each cell's best time. A variant excluded for one file (or in one log) is excluded
|
||||
for every file of that use case. The reference values that bench_all and bench_rs print for sum and select are
|
||||
compared, so both programs are known to have checked against the same numbers.
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
USE_CASES = ["validate", "sum", "select", "edit", "minify", "write"]
|
||||
DOCS = ["twitter", "citm_catalog", "canada", "jeopardy", "status", "twitter_min", "citm_catalog_min"]
|
||||
OURS = "nlohmann json_document"
|
||||
RANK = {"full": 0, "n/a": 0, "no UTF-8": 1, "partial": 2}
|
||||
CELL = re.compile(r"^(.+) \[(full|no UTF-8|partial|n/a)\] ([\d.]+)us(?: \(([\d.]+)x\))?$")
|
||||
REF = re.compile(r"^check (\S+)\s+(\S+)\s+reference: (.*)$")
|
||||
|
||||
|
||||
def library(name):
|
||||
return name.split(": ", 1)[0]
|
||||
|
||||
|
||||
def variant(name):
|
||||
return name.split(": ", 1)[1] if ": " in name else name
|
||||
|
||||
|
||||
def is_reused(name):
|
||||
return re.search(r"\(reused[ )]", name) is not None
|
||||
|
||||
|
||||
def is_untimed_copy(name):
|
||||
return "(copy untimed)" in name
|
||||
|
||||
|
||||
def worse(a, b):
|
||||
return a if a is not None and (b is None or RANK[a] >= RANK[b]) else b
|
||||
|
||||
|
||||
def parse(path, cells, levels, notes, excluded, refs):
|
||||
for line in open(path, encoding="utf-8"):
|
||||
line = line.rstrip("\n")
|
||||
if line.startswith(("excluded: ", "level: ")):
|
||||
kind, rest = line.split(": ", 1)
|
||||
fields = rest.split(" | ")
|
||||
doc, uc = fields[0].split()
|
||||
name = fields[1]
|
||||
target = excluded if kind == "excluded" else notes
|
||||
for why in fields[-1].split("; "):
|
||||
target.setdefault((uc, name), {}).setdefault(why, set()).add(doc)
|
||||
if kind == "level":
|
||||
levels[(uc, name)] = worse(levels.get((uc, name)), fields[2])
|
||||
continue
|
||||
m = REF.match(line)
|
||||
if m:
|
||||
refs.setdefault((m[1], m[2]), {})[path] = m[3]
|
||||
continue
|
||||
if line.startswith(("check", "done", "WARNING")) or " | " not in line:
|
||||
continue
|
||||
parts = line.split(" | ")
|
||||
head = parts[0].split()
|
||||
if len(head) != 2 or head[1] not in USE_CASES:
|
||||
continue
|
||||
for c in parts[1:]:
|
||||
m = CELL.match(c.strip())
|
||||
if m:
|
||||
key = (head[0], head[1], m[1])
|
||||
if head[0] not in DOCS: # bench_all --files: the documents are the files of a directory
|
||||
DOCS.append(head[0])
|
||||
cells[key] = min(cells.get(key, float("inf")), float(m[3]))
|
||||
levels[(head[1], m[1])] = worse(levels.get((head[1], m[1])), m[2])
|
||||
|
||||
|
||||
def check_refs(refs):
|
||||
"""The sum and select references of all logs must agree (bench_rs prints Rust's float formatting)."""
|
||||
def numbers(text):
|
||||
return [float(x) for x in re.findall(r"[-+]?\d[\d.]*(?:e[-+]?\d+)?", text)]
|
||||
ok = True
|
||||
for (doc, uc), by_log in sorted(refs.items()):
|
||||
values = {tuple(numbers(t)) for t in by_log.values()}
|
||||
if len(values) > 1:
|
||||
ok = False
|
||||
print("WARNING: the %s %s references differ: %s" % (doc, uc, "; ".join("%s: %s" % kv for kv in by_log.items())))
|
||||
return ok
|
||||
|
||||
|
||||
def is_full(level):
|
||||
return RANK[level] == 0
|
||||
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
out_json = None
|
||||
if "--json" in args:
|
||||
i = args.index("--json")
|
||||
out_json = args[i + 1]
|
||||
del args[i:i + 2]
|
||||
cpp = args[:args.index("--rust")] if "--rust" in args else args
|
||||
rust = args[args.index("--rust") + 1:] if "--rust" in args else []
|
||||
if not cpp and not rust:
|
||||
sys.exit(__doc__)
|
||||
cells, levels, notes, excluded, refs = {}, {}, {}, {}, {}
|
||||
for p in cpp + rust:
|
||||
parse(p, cells, levels, notes, excluded, refs)
|
||||
check_refs(refs)
|
||||
result = {}
|
||||
|
||||
def docs_of(uc):
|
||||
return [d for d in DOCS if any(k[0] == d and k[1] == uc for k in cells)]
|
||||
|
||||
def cell_of(doc, uc):
|
||||
return {n: t for (d, u, n), t in cells.items() if d == doc and u == uc and (uc, n) not in excluded}
|
||||
|
||||
def show(n, t, ours, uc):
|
||||
ratio = "%5.2f" % (t / ours) if ours else " -"
|
||||
return "%-40s %-10s %11.1f us %s" % (variant(n), "[%s]" % levels[(uc, n)], t, ratio)
|
||||
|
||||
print("# (a) Per library: the best full variant, and the best at any level if faster (ratio to the best full %s"
|
||||
" variant; below 1: faster)" % OURS)
|
||||
for uc in USE_CASES:
|
||||
if not docs_of(uc):
|
||||
continue
|
||||
print("\n== " + uc)
|
||||
for doc in docs_of(uc):
|
||||
cell = cell_of(doc, uc)
|
||||
libs = {}
|
||||
for n, t in cell.items():
|
||||
libs.setdefault(library(n), {})[n] = t
|
||||
entry = result.setdefault(uc, {}).setdefault(doc, {})
|
||||
rows = []
|
||||
def pick(vs):
|
||||
"""the best full variant and the best variant at any level"""
|
||||
full = {n: t for n, t in vs.items() if is_full(levels[(uc, n)])}
|
||||
return (min(full.items(), key=lambda x: x[1]) if full else None,
|
||||
min(vs.items(), key=lambda x: x[1]) if vs else None)
|
||||
|
||||
def described(x):
|
||||
return {"variant": variant(x[0]), "us": x[1], "level": levels[(uc, x[0])]} if x else None
|
||||
|
||||
for lib, vs in libs.items():
|
||||
b, a = pick({n: t for n, t in vs.items() if not is_reused(n) and not is_untimed_copy(n)})
|
||||
rb, ra = pick({n: t for n, t in vs.items() if is_reused(n)})
|
||||
entry[lib] = {
|
||||
"best": described(b),
|
||||
"best_any": described(a),
|
||||
"best_reused": described(rb),
|
||||
"best_reused_any": described(ra),
|
||||
"variants": {variant(n): {"us": t, "level": levels[(uc, n)]} for n, t in sorted(vs.items(), key=lambda x: x[1])},
|
||||
}
|
||||
rows.append((lib, b, a, rb, ra))
|
||||
for (u, n), whys in excluded.items():
|
||||
if u == uc:
|
||||
lib = entry.setdefault(library(n), {"best": None, "best_any": None, "best_reused": None, "best_reused_any": None, "variants": {}})
|
||||
lib.setdefault("excluded", {})[variant(n)] = "; ".join(sorted(whys))
|
||||
ours = next((b[1] for lib, b, a, rb, ra in rows if lib == OURS and b), None)
|
||||
print("%s%s" % (doc, "" if ours else " (no full %s result)" % OURS))
|
||||
rows.sort(key=lambda r: (r[1] is None, r[1][1] if r[1] else r[2][1] if r[2] else 0))
|
||||
for lib, b, a, rb, ra in rows:
|
||||
line = " %-24s %s" % (lib, show(*b, ours, uc) if b else "%-40s %-10s %14s %5s" % ("(none)", "", "", ""))
|
||||
if a and (not b or a[0] != b[0]):
|
||||
line += " | faster: %s" % show(*a, ours, uc)
|
||||
print(line)
|
||||
if ra:
|
||||
line = " %-22s %s" % ("reused:", show(*rb, ours, uc) if rb else "%-40s %-10s %14s %5s" % ("(none)", "", "", ""))
|
||||
if not rb or ra[0] != rb[0]:
|
||||
line += " | faster: %s" % show(*ra, ours, uc)
|
||||
print(line)
|
||||
|
||||
print("\n# (b) All variants")
|
||||
for uc in USE_CASES:
|
||||
if not docs_of(uc):
|
||||
continue
|
||||
print("\n== " + uc)
|
||||
for doc in docs_of(uc):
|
||||
cell = cell_of(doc, uc)
|
||||
ours = min((t for n, t in cell.items() if library(n) == OURS and not is_reused(n) and is_full(levels[(uc, n)])), default=None)
|
||||
print(doc)
|
||||
for n, t in sorted(cell.items(), key=lambda x: x[1]):
|
||||
ratio = "%5.2f" % (t / ours) if ours else " -"
|
||||
print(" %-66s %-10s %11.1f us %s" % (n, "[%s]" % levels[(uc, n)], t, ratio))
|
||||
|
||||
print("\n# (c) Variants below full, and excluded variants")
|
||||
for uc in USE_CASES:
|
||||
rows = sorted((n, whys) for (u, n), whys in notes.items() if u == uc)
|
||||
ex = sorted((n, whys) for (u, n), whys in excluded.items() if u == uc)
|
||||
if not rows and not ex:
|
||||
continue
|
||||
print("\n== " + uc)
|
||||
for n, whys in rows:
|
||||
for why, docs in sorted(whys.items()):
|
||||
print(" %-58s %-10s %s (%s)" % (n, "[%s]" % levels.get((uc, n), "?"), why, ", ".join(d for d in DOCS if d in docs)))
|
||||
for n, whys in ex:
|
||||
for why, docs in sorted(whys.items()):
|
||||
print(" %-58s %-10s %s (%s)" % (n, "excluded", why, ", ".join(d for d in DOCS if d in docs)))
|
||||
|
||||
if out_json:
|
||||
with open(out_json, "w", encoding="utf-8") as f:
|
||||
json.dump(result, f, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,34 @@
|
||||
# check_path_filters
|
||||
|
||||
The compiler workflows [`ubuntu.yml`](../../.github/workflows/ubuntu.yml),
|
||||
[`macos.yml`](../../.github/workflows/macos.yml), and [`windows.yml`](../../.github/workflows/windows.yml) skip pull
|
||||
requests that change only files no compiler job reads: the documentation, Markdown files, GitHub metadata, other
|
||||
workflows, and the license files. Pushes to `develop`, `master`, and `release/*` always run them. The documentation,
|
||||
license, and path-filter checks run in [`repository_checks.yml`](../../.github/workflows/repository_checks.yml), which
|
||||
has no path filter.
|
||||
|
||||
The filter starts with `'**'` and excludes these files explicitly, so a new file runs the compiler workflows unless it
|
||||
is excluded on purpose. [`check_path_filters.py`](check_path_filters.py) holds the filter (`PATHS`) and checks that
|
||||
|
||||
- each of the three workflows has exactly this filter, with its own workflow file included,
|
||||
- the CI targets that read excluded files (`UNFILTERED_TARGETS`) do not run in these workflows, and
|
||||
- no file the filter keeps (sources, tests, build files, tools, workflows) mentions an excluded file or directory
|
||||
outside a comment line, unless the mention is listed in `KNOWN_REFERENCES` with a reason.
|
||||
|
||||
When the check reports a mention, decide whether a compiler job reads that file:
|
||||
|
||||
- If it does, include the file in `PATHS` after the exclusions (as `package_managers.md` and the Swift example are) and
|
||||
copy the new filter into the three workflows.
|
||||
- If it does not, add the mention to `KNOWN_REFERENCES` with the reason.
|
||||
|
||||
Run the check with
|
||||
|
||||
```shell
|
||||
python3 tools/check_path_filters/check_path_filters.py
|
||||
```
|
||||
|
||||
To see which workflows a pull request would run, pass the changed files:
|
||||
|
||||
```shell
|
||||
python3 tools/check_path_filters/check_path_filters.py --changed $(git diff --name-only origin/develop)
|
||||
```
|
||||
@@ -0,0 +1,273 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check the path filters of the compiler workflows.
|
||||
|
||||
ubuntu.yml, macos.yml and windows.yml skip pull requests that change only files
|
||||
no compiler job reads (documentation, Markdown files, GitHub metadata, license
|
||||
files). The filter starts with '**' and excludes these files explicitly, so a
|
||||
new file runs the workflows unless it is excluded on purpose.
|
||||
|
||||
The script checks that
|
||||
|
||||
- each of the three workflows has exactly the filter defined in PATHS below,
|
||||
with its own workflow file included, and
|
||||
- no tracked file that the filter keeps (sources, tests, build files, tools,
|
||||
workflows) mentions a file the filter excludes, unless the mention is listed
|
||||
in KNOWN_REFERENCES with the reason why it does not matter.
|
||||
|
||||
A mention found this way must either be added to PATHS as an included path
|
||||
(the file is read by a compiler job) or to KNOWN_REFERENCES (it is not).
|
||||
|
||||
With --changed FILE..., the script prints instead which workflows a pull
|
||||
request changing these files would run.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess # nosec B404
|
||||
import sys
|
||||
|
||||
REPO_ROOT = os.path.normpath(os.path.join(sys.path[0], '..', '..'))
|
||||
SELF = 'tools/check_path_filters/check_path_filters.py'
|
||||
|
||||
WORKFLOWS = ['.github/workflows/ubuntu.yml', '.github/workflows/macos.yml', '.github/workflows/windows.yml']
|
||||
|
||||
# The pull_request paths filter of the workflows above; '{workflow}' is replaced
|
||||
# with the workflow's own file. GitHub applies the patterns in order: a file
|
||||
# matching a later pattern is included ('pattern') or excluded ('!pattern').
|
||||
PATHS = [
|
||||
'**',
|
||||
'!docs/**',
|
||||
'!**.md',
|
||||
'!.github/*',
|
||||
'!.github/ISSUE_TEMPLATE/**',
|
||||
'!.github/external_ci/**',
|
||||
'!.github/workflows/**',
|
||||
'!.reuse/**',
|
||||
'!LICENSES/**',
|
||||
'!CITATION.cff',
|
||||
'!REUSE.toml',
|
||||
# read by tools/check_build_options in the ci_meson_install job (ubuntu.yml)
|
||||
'docs/mkdocs/docs/integration/package_managers.md',
|
||||
# built by the swiftpm job (macos.yml)
|
||||
'docs/mkdocs/docs/integration/swift/**',
|
||||
'{workflow}',
|
||||
]
|
||||
|
||||
# Mentions of excluded files that no job of the three workflows depends on:
|
||||
# (file that mentions it, the mention, reason)
|
||||
KNOWN_REFERENCES = [
|
||||
('cmake/ci.cmake', 'docs/', 'ci_test_examples; runs in repository_checks.yml, which has no path filter'),
|
||||
('cmake/ci.cmake', 'docs/mkdocs/', 'ci_test_build_documentation and ci_test_documentation_mermaid; they run in '
|
||||
'repository_checks.yml, which has no path filter'),
|
||||
('cmake/ci.cmake', 'docs/mkdocs/docs/examples/', 'indentation check of ci_test_amalgamation; the same check runs in '
|
||||
'check_amalgamation.yml, which has no path filter'),
|
||||
('Makefile', 'docs/mkdocs/docs/examples/', 'make pretty; runs in check_amalgamation.yml, which has no path filter'),
|
||||
('Makefile', 'ChangeLog.md', 'make ChangeLog.md writes the file; no CI job runs it'),
|
||||
('Makefile', 'tests/fuzzing.md', 'help text'),
|
||||
('Makefile', 'tools/generate_natvis/README.md', 'help text'),
|
||||
('tests/src/make_test_data_available.hpp', 'README.md', 'a file of the external test data repository'),
|
||||
('tools/check_build_options/check_build_options.py', 'docs/', 'builds the path of package_managers.md, which '
|
||||
'PATHS includes'),
|
||||
('tools/ci_jobs/ci_jobs.py', 'docs/mkdocs/docs/community/quality_assurance.md',
|
||||
'checks the job table; runs in repository_checks.yml, which has no path filter'),
|
||||
('tools/ci_jobs/ci_jobs.py', '.github/workflows/repository_checks.yml', 'read by --compare, a manual check'),
|
||||
('tools/ci_jobs/ci_jobs.py', '.github/workflows/check_amalgamation.yml', 'read by --compare, a manual check'),
|
||||
]
|
||||
|
||||
|
||||
# CI targets that read excluded files; they must run in a workflow without a path filter
|
||||
UNFILTERED_TARGETS = ['ci_test_examples', 'ci_test_build_documentation', 'ci_test_documentation_mermaid',
|
||||
'ci_test_amalgamation', 'ci_reuse_compliance']
|
||||
|
||||
|
||||
def git_files(root):
|
||||
# fixed command, no user input; includes new files not yet added, so a local run
|
||||
# sees what CI sees after the commit
|
||||
out = subprocess.check_output(['git', 'ls-files', '-z', '--cached', '--others', '--exclude-standard'], cwd=root) # nosec B603, B607
|
||||
return [f for f in out.decode('utf-8').split('\0') if f]
|
||||
|
||||
|
||||
def glob_to_regex(pattern):
|
||||
"""Translate a GitHub Actions path pattern to a regular expression."""
|
||||
regex = ''
|
||||
i = 0
|
||||
while i < len(pattern):
|
||||
if pattern.startswith('**', i):
|
||||
regex += '.*'
|
||||
i += 2
|
||||
elif pattern[i] == '*':
|
||||
regex += '[^/]*'
|
||||
i += 1
|
||||
elif pattern[i] == '?':
|
||||
regex += '[^/]'
|
||||
i += 1
|
||||
else:
|
||||
regex += re.escape(pattern[i])
|
||||
i += 1
|
||||
return re.compile(regex + r'\Z')
|
||||
|
||||
|
||||
def compile_filter(paths, workflow):
|
||||
return [(p.startswith('!'), glob_to_regex(p.lstrip('!').replace('{workflow}', workflow))) for p in paths]
|
||||
|
||||
|
||||
def included(compiled, path):
|
||||
result = False
|
||||
for negated, regex in compiled:
|
||||
if regex.match(path):
|
||||
result = not negated
|
||||
return result
|
||||
|
||||
|
||||
def read_filter(root, workflow):
|
||||
"""Return the pull_request paths list of a workflow file."""
|
||||
with open(os.path.join(root, workflow), encoding='utf-8') as f:
|
||||
lines = f.read().splitlines()
|
||||
paths = None
|
||||
in_pull_request = False
|
||||
for line in lines:
|
||||
if re.match(r'^ pull_request:', line):
|
||||
in_pull_request = True
|
||||
continue
|
||||
if in_pull_request:
|
||||
if re.match(r'^ \S', line) or re.match(r'^\S', line):
|
||||
break
|
||||
if re.match(r'^ paths:\s*$', line):
|
||||
paths = []
|
||||
continue
|
||||
m = re.match(r"^ - '(.*)'\s*(#.*)?$", line)
|
||||
if paths is not None and m:
|
||||
paths.append(m.group(1))
|
||||
elif paths is not None and line.strip() and not line.strip().startswith('#'):
|
||||
break
|
||||
return paths
|
||||
|
||||
|
||||
TOKEN = re.compile(r'(["\'/]?)([\w.-]+(?:/[\w.-]+)*)')
|
||||
|
||||
|
||||
COMMENT_LINE = re.compile(r'^[ \t]*(//|#|/?\*|--).*$', re.MULTILINE)
|
||||
|
||||
|
||||
class Mentions:
|
||||
"""Finds the words and paths in a text that name an excluded file or directory."""
|
||||
|
||||
def __init__(self, files, excluded, is_excluded):
|
||||
self.files = set(files)
|
||||
self.excluded = excluded
|
||||
self.dirs = {'/'.join(f.split('/')[:n]) for f in files for n in range(1, f.count('/') + 1)}
|
||||
# an excluded directory: a new file in it would be excluded
|
||||
self.excluded_dirs = {d for d in self.dirs if is_excluded(d + '/new_file')}
|
||||
# base names that only excluded files have, e.g. 'ChangeLog.md' but not 'CMakeLists.txt'
|
||||
self.names = {os.path.basename(f) for f in excluded} - {os.path.basename(f) for f in files if f not in excluded}
|
||||
|
||||
def find(self, text):
|
||||
"""Yield (offset, mention) for every word or path in text that names an excluded file or directory."""
|
||||
for m in TOKEN.finditer(text):
|
||||
parts = m.group(2).rstrip('/').split('/')
|
||||
# a single word names a directory only in a path context, e.g. 'docs' in os.path.join('docs', ...)
|
||||
path_context = len(parts) > 1 or m.group(1)
|
||||
for i in range(len(parts)):
|
||||
path = '/'.join(parts[i:])
|
||||
if path in self.files:
|
||||
if path in self.excluded:
|
||||
yield m.start(2), path
|
||||
break
|
||||
if path in self.dirs and path_context:
|
||||
if path in self.excluded_dirs:
|
||||
yield m.start(2), path + '/'
|
||||
break
|
||||
else:
|
||||
if parts[-1] in self.names and '.' in parts[-1]:
|
||||
yield m.start(2), parts[-1]
|
||||
|
||||
|
||||
def known(path, mention):
|
||||
return any(path == file and mention == known_mention for file, known_mention, _ in KNOWN_REFERENCES)
|
||||
|
||||
|
||||
def check_workflows(root):
|
||||
"""Return the errors in the filters of the workflows and in the targets they run."""
|
||||
errors = []
|
||||
for workflow in WORKFLOWS:
|
||||
expected = [p.replace('{workflow}', workflow) for p in PATHS]
|
||||
actual = read_filter(root, workflow)
|
||||
if actual != expected:
|
||||
errors.append('{}: the pull_request paths filter differs from tools/check_path_filters/check_path_filters.py\n'
|
||||
' expected: {}\n actual: {}'.format(workflow, expected, actual))
|
||||
with open(os.path.join(root, workflow), encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
errors += ['{}: runs {}, which reads excluded files; run it in repository_checks.yml'.format(workflow, target)
|
||||
for target in UNFILTERED_TARGETS if re.search(r'\b' + target + r'\b', text)]
|
||||
return errors
|
||||
|
||||
|
||||
def scanned_text(root, path):
|
||||
"""Return the text of a kept file without comment lines and without the filter itself, or None to skip it."""
|
||||
# third-party code and Markdown files read nothing; this script lists the excluded files
|
||||
if path.startswith('tests/thirdparty/') or path.endswith('.md') or path == SELF:
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(root, path), encoding='utf-8') as f:
|
||||
# a mention in a comment line reads nothing; keep the line numbers
|
||||
text = COMMENT_LINE.sub('', f.read())
|
||||
except (UnicodeDecodeError, OSError):
|
||||
return None
|
||||
if path in WORKFLOWS:
|
||||
# the filter itself lists the excluded files
|
||||
for p in PATHS:
|
||||
text = text.replace(" - '{}'".format(p.replace('{workflow}', path)), '')
|
||||
return text
|
||||
|
||||
|
||||
def check_mentions(root, files, excluded, finder):
|
||||
"""Return an error for every mention of an excluded file in a kept file that KNOWN_REFERENCES does not list."""
|
||||
errors = []
|
||||
for path in sorted(set(files) - excluded):
|
||||
text = scanned_text(root, path)
|
||||
reported = set()
|
||||
for offset, mention in finder.find(text or ''):
|
||||
if mention not in reported and not known(path, mention):
|
||||
reported.add(mention)
|
||||
line = text.count('\n', 0, offset) + 1
|
||||
errors.append('{}:{}: mentions excluded {}; include it in PATHS if a compiler job reads it, '
|
||||
'or add it to KNOWN_REFERENCES'.format(path, line, mention))
|
||||
return errors
|
||||
|
||||
|
||||
def check(root):
|
||||
files = git_files(root)
|
||||
union = [compile_filter(PATHS, w) for w in WORKFLOWS]
|
||||
|
||||
def is_excluded(path):
|
||||
return not any(included(c, path) for c in union)
|
||||
|
||||
excluded = {f for f in files if is_excluded(f)}
|
||||
errors = check_workflows(root) + check_mentions(root, files, excluded, Mentions(files, excluded, is_excluded))
|
||||
for e in errors:
|
||||
print(e)
|
||||
if not errors:
|
||||
print('path filters OK: {} of {} tracked files skip the compiler workflows'.format(len(excluded), len(files)))
|
||||
return 1 if errors else 0
|
||||
|
||||
|
||||
def explain(changed):
|
||||
for workflow in WORKFLOWS:
|
||||
compiled = compile_filter(PATHS, workflow)
|
||||
hits = [f for f in changed if included(compiled, f)]
|
||||
print('{}: {}'.format(workflow, 'runs ({})'.format(', '.join(hits[:3]) + (' ...' if len(hits) > 3 else ''))
|
||||
if hits else 'skipped'))
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument('--root', default=REPO_ROOT, help='repository root')
|
||||
parser.add_argument('--changed', nargs='+', metavar='FILE', help='show which workflows these changed files run')
|
||||
args = parser.parse_args()
|
||||
return explain(args.changed) if args.changed else check(args.root)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,30 @@
|
||||
# ci_jobs
|
||||
|
||||
The jobs of the compiler workflows [`ubuntu.yml`](../../.github/workflows/ubuntu.yml),
|
||||
[`macos.yml`](../../.github/workflows/macos.yml), and [`windows.yml`](../../.github/workflows/windows.yml) are split into
|
||||
three sets, chosen by each job's
|
||||
`if:` condition (see [How CI runs](https://json.nlohmann.me/community/quality_assurance/#how-ci-runs)):
|
||||
|
||||
- **PR set**: every push to a pull request, and every push to `develop`, `master`, and `release/*`;
|
||||
- **full set**: after the PR set passed, on pull requests with the label "🚀 ready to merge" and on every push;
|
||||
- **nightly set**: every night on `develop`, on every push to `master` and `release/*`, and when started by hand.
|
||||
|
||||
A matrix whose entries belong to different sets is split into one job per set: the full-set job gets the suffix
|
||||
`_full`, the nightly-set job `_nightly`, and both share their steps with the PR-set job through YAML anchors.
|
||||
|
||||
[`ci_jobs.py`](ci_jobs.py) checks that
|
||||
|
||||
- every job has the `if:` condition of exactly one set (the conditions are in `SETS`),
|
||||
- every full-set job waits for (`needs:`) exactly the PR set of its workflow, and `nightly_report` for exactly the
|
||||
nightly set, and
|
||||
- the job table in [`quality_assurance.md`](../../docs/mkdocs/docs/community/quality_assurance.md) is up to date.
|
||||
|
||||
```shell
|
||||
python3 -m venv venv && venv/bin/pip install -r tools/ci_jobs/requirements.txt
|
||||
venv/bin/python tools/ci_jobs/ci_jobs.py # check
|
||||
venv/bin/python tools/ci_jobs/ci_jobs.py --markdown # print the job table for the documentation
|
||||
venv/bin/python tools/ci_jobs/ci_jobs.py --compare origin/develop # list configurations added or removed since develop
|
||||
```
|
||||
|
||||
Use `--compare` when changing the workflows: a configuration that disappears fails it, so no compiler, version, or
|
||||
standard is dropped by accident when jobs are split, merged, or moved between sets.
|
||||
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env python3
|
||||
"""List and check the jobs of the compiler workflows and the set each job belongs to.
|
||||
|
||||
The jobs of the compiler workflows belong to one of three sets, chosen by the
|
||||
job's `if:` condition:
|
||||
|
||||
- PR set: every pull request push and every push,
|
||||
- full set: after the PR set passed, on pushes and on pull requests with the
|
||||
"🚀 ready to merge" label,
|
||||
- nightly set: nightly on develop, on pushes to master and release/*, and when
|
||||
started by hand.
|
||||
|
||||
The script checks that every job belongs to exactly one set, that the full set
|
||||
of a workflow waits for its whole PR set, that the nightly report waits for the
|
||||
whole nightly set, and that the job table in
|
||||
docs/mkdocs/docs/community/quality_assurance.md is up to date.
|
||||
|
||||
--markdown print the job table for the documentation
|
||||
--compare REF list the configurations (job and matrix values) added or
|
||||
removed since the git revision REF; fails if one was removed
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import subprocess # nosec B404
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
REPO_ROOT = os.path.normpath(os.path.join(sys.path[0], '..', '..'))
|
||||
DOCS = 'docs/mkdocs/docs/community/quality_assurance.md'
|
||||
BEGIN, END = '<!-- ci_jobs: begin -->', '<!-- ci_jobs: end -->'
|
||||
|
||||
WORKFLOWS = ['.github/workflows/ubuntu.yml', '.github/workflows/macos.yml', '.github/workflows/windows.yml']
|
||||
TIERED = WORKFLOWS
|
||||
# --compare also counts the jobs of these workflows, so a job moved between workflows is not a removed one
|
||||
COMPARED = WORKFLOWS + ['.github/workflows/repository_checks.yml', '.github/workflows/check_amalgamation.yml']
|
||||
|
||||
LABEL = '🚀 ready to merge'
|
||||
SETS = collections.OrderedDict([
|
||||
('PR set', "${{ github.event_name != 'schedule' && (github.event.action != 'labeled' || "
|
||||
"github.event.label.name == '" + LABEL + "') }}"),
|
||||
('full set', "${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || "
|
||||
"contains(github.event.pull_request.labels.*.name, '" + LABEL + "') }}"),
|
||||
('nightly set', "${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || "
|
||||
"(github.event_name == 'push' && github.ref != 'refs/heads/develop') }}"),
|
||||
])
|
||||
UNTIERED = 'every push and PR'
|
||||
REPORT_JOB = 'nightly_report'
|
||||
|
||||
# a job split by set keeps its name and gets one of these suffixes
|
||||
SUFFIXES = {'full set': '_full', 'nightly set': '_nightly'}
|
||||
|
||||
|
||||
def read(root, path, ref=None):
|
||||
if ref is None:
|
||||
with open(os.path.join(root, path), encoding='utf-8') as f:
|
||||
return f.read()
|
||||
# fixed command; ref is a git revision given on the command line
|
||||
return subprocess.check_output(['git', 'show', '{}:{}'.format(ref, path)], cwd=root, # nosec B603, B607
|
||||
stderr=subprocess.DEVNULL).decode('utf-8')
|
||||
|
||||
|
||||
def add_include(combos, keys, inc):
|
||||
"""Apply one include entry: extend the matching configurations, or add it as a new one."""
|
||||
matching = [c for c in combos if all(c[k] == v for k, v in inc.items() if k in keys)]
|
||||
for c in matching:
|
||||
c.update({k: v for k, v in inc.items() if k not in keys})
|
||||
if not matching:
|
||||
combos.append(dict(inc))
|
||||
|
||||
|
||||
def expand(matrix):
|
||||
"""Return the configurations of a job's strategy.matrix like GitHub Actions does."""
|
||||
if not matrix:
|
||||
return [{}]
|
||||
keys = [k for k in matrix if k not in ('include', 'exclude')]
|
||||
if not keys:
|
||||
# a matrix of only include entries runs each entry
|
||||
return [dict(inc) for inc in matrix.get('include') or []]
|
||||
combos = [dict(zip(keys, values)) for values in itertools.product(*(matrix[k] for k in keys))]
|
||||
for ex in matrix.get('exclude') or []:
|
||||
combos = [c for c in combos if any(c.get(k) != v for k, v in ex.items())]
|
||||
for inc in matrix.get('include') or []:
|
||||
add_include(combos, keys, inc)
|
||||
return combos
|
||||
|
||||
|
||||
def jobs_of(root, workflow, ref=None):
|
||||
"""Yield (job id, set, list of configurations) for every job of a workflow."""
|
||||
data = yaml.safe_load(read(root, workflow, ref))
|
||||
for job_id, job in data['jobs'].items():
|
||||
condition = job.get('if')
|
||||
job_set = UNTIERED if condition is None else next((s for s, c in SETS.items() if c == condition), None)
|
||||
matrix = (job.get('strategy') or {}).get('matrix')
|
||||
yield job_id, job_set, job, expand(matrix)
|
||||
|
||||
|
||||
def base_id(job_id, job_set):
|
||||
suffix = SUFFIXES.get(job_set)
|
||||
return job_id[:-len(suffix)] if suffix and job_id.endswith(suffix) else job_id
|
||||
|
||||
|
||||
def label(config):
|
||||
return ', '.join(str(v) for k, v in config.items() if k != 'os' or len(config) == 1)
|
||||
|
||||
|
||||
def configurations(root, ref=None):
|
||||
"""Return a Counter of (job name without set suffix, configuration) over the compared workflows."""
|
||||
result = collections.Counter()
|
||||
for workflow in COMPARED:
|
||||
try:
|
||||
jobs = list(jobs_of(root, workflow, ref))
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
continue # the workflow does not exist in this revision
|
||||
for job_id, job_set, _, configs in jobs:
|
||||
if job_id == REPORT_JOB:
|
||||
continue
|
||||
for c in configs:
|
||||
result[(base_id(job_id, job_set), tuple(sorted((k, str(v)) for k, v in c.items())))] += 1
|
||||
return result
|
||||
|
||||
|
||||
def markdown(root):
|
||||
rows = []
|
||||
order = list(SETS) + [UNTIERED]
|
||||
for workflow in WORKFLOWS:
|
||||
for job_id, job_set, _, configs in jobs_of(root, workflow):
|
||||
if job_id == REPORT_JOB:
|
||||
continue
|
||||
labels = [label(c) for c in configs if c]
|
||||
rows.append((order.index(job_set) if job_set in order else len(order), os.path.basename(workflow), job_id,
|
||||
job_set or 'no set', '; '.join(labels) or '-'))
|
||||
rows.sort(key=lambda r: (r[0], r[1]))
|
||||
lines = ['| Set | Workflow | Job | Configurations |', '|-----|----------|-----|----------------|']
|
||||
lines += ['| {} | {} | `{}` | {} |'.format(s, w, j, c) for _, w, j, s, c in rows]
|
||||
return lines
|
||||
|
||||
|
||||
def check_sets(workflow, jobs):
|
||||
"""Return the errors in the sets of a tiered workflow's jobs and the jobs of each set."""
|
||||
errors = []
|
||||
by_set = collections.defaultdict(set)
|
||||
for job_id, job_set, _, _ in jobs:
|
||||
if job_id == REPORT_JOB:
|
||||
continue
|
||||
if job_set in SETS:
|
||||
by_set[job_set].add(job_id)
|
||||
else:
|
||||
errors.append('{}: job {} has an if: condition of no set; use one of the conditions in '
|
||||
'tools/ci_jobs/ci_jobs.py'.format(workflow, job_id))
|
||||
return errors, by_set
|
||||
|
||||
|
||||
def check_needs(workflow, jobs, by_set):
|
||||
"""Return the errors in the needs: of a tiered workflow's jobs."""
|
||||
required = {'full set': by_set['PR set'], 'PR set': set(), 'nightly set': set()}
|
||||
errors = []
|
||||
for job_id, job_set, job, _ in jobs:
|
||||
needs = job.get('needs') or []
|
||||
needs = {needs} if isinstance(needs, str) else set(needs)
|
||||
expected = by_set['nightly set'] if job_id == REPORT_JOB else required.get(job_set, needs)
|
||||
if needs != expected:
|
||||
errors.append('{}: job {} must need exactly: {}'.format(workflow, job_id, ', '.join(sorted(expected)) or 'no job'))
|
||||
return errors
|
||||
|
||||
|
||||
def check_docs(root):
|
||||
"""Return an error if the job table in the documentation is not up to date."""
|
||||
text = read(root, DOCS)
|
||||
block = re.search(re.escape(BEGIN) + r'\n(.*?)\n[ \t]*' + re.escape(END), text, re.S)
|
||||
if not block:
|
||||
return ['{}: markers {} and {} not found'.format(DOCS, BEGIN, END)]
|
||||
indent = re.match(r'[ \t]*', block.group(1)).group(0)
|
||||
if block.group(1) != '\n'.join(indent + line for line in markdown(root)):
|
||||
return ['{}: the job table is out of date; replace it with the output of '
|
||||
'python3 tools/ci_jobs/ci_jobs.py --markdown'.format(DOCS)]
|
||||
return []
|
||||
|
||||
|
||||
def check(root):
|
||||
errors = []
|
||||
for workflow in TIERED:
|
||||
jobs = list(jobs_of(root, workflow))
|
||||
set_errors, by_set = check_sets(workflow, jobs)
|
||||
errors += set_errors + check_needs(workflow, jobs, by_set)
|
||||
errors += check_docs(root)
|
||||
|
||||
for e in errors:
|
||||
print(e)
|
||||
if not errors:
|
||||
counts = collections.Counter()
|
||||
for workflow in WORKFLOWS:
|
||||
for job_id, job_set, _, configs in jobs_of(root, workflow):
|
||||
if job_id != REPORT_JOB:
|
||||
counts[job_set] += len(configs)
|
||||
print('CI jobs OK: ' + ', '.join('{} {}'.format(n, s) for s, n in counts.items()))
|
||||
return 1 if errors else 0
|
||||
|
||||
|
||||
def compare(root, ref):
|
||||
before, after = configurations(root, ref), configurations(root)
|
||||
removed, added = before - after, after - before
|
||||
for title, diff in (('removed', removed), ('added', added)):
|
||||
for job, config in sorted(diff.elements()):
|
||||
print('{}: {} ({})'.format(title, job, ', '.join('{}={}'.format(k, v) for k, v in config)))
|
||||
print('{} configurations before, {} after; {} removed, {} added'.format(
|
||||
sum(before.values()), sum(after.values()), sum(removed.values()), sum(added.values())))
|
||||
return 1 if removed else 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument('--root', default=REPO_ROOT, help='repository root')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument('--markdown', action='store_true', help='print the job table for the documentation')
|
||||
group.add_argument('--compare', metavar='REF', help='list the configurations added or removed since REF')
|
||||
args = parser.parse_args()
|
||||
if args.markdown:
|
||||
print('\n'.join(markdown(args.root)))
|
||||
return 0
|
||||
if args.compare:
|
||||
return compare(args.root, args.compare)
|
||||
return check(args.root)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1 @@
|
||||
PyYAML==6.0.3
|
||||