Idea: apply the & ~v once in the SWAR scans that let non-ASCII bytes through

Aperta
#6,063 1 commento 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@Krishna221308 ci sta già lavorando.

Dal 13/11/2026.

  • #6099 di @Krishna221308 — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
1-2 giorni
Idoneità per principianti
55/100
Tipo di issue
Refactoring
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
cpp

Direzione di ricerca

Read find_string_delimiter() in include/nlohmann/detail/input/string_scan.hpp and the SWAR tail of plain_output_run() in include/nlohmann/detail/view/serializer.hpp. First compare the old and proposed masks with GCC and Clang generated code, then run the issue's random-word and adjacent-byte checks and the existing test suite with JSON_USE_SIMDUTF and JSON_NO_SIMD. Done means the masks match bit for bit and the change shows a worthwhile instruction reduction.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Idea

#6033 drops the & ~x from the 8-byte (SWAR) tests for special bytes in strings, wherever bytes from 0x80 are stops anyway. Two SWAR scans let bytes from 0x80 through, so they still need the & ~x. Each of them still applies it three times:

  • find_string_delimiter() in include/nlohmann/detail/input/string_scan.hpp (only with JSON_USE_SIMDUTF and C++17), which hands non-ASCII runs to simdutf;
  • the SWAR tail of plain_output_run() in include/nlohmann/detail/view/serializer.hpp, which handles the last 8–15 bytes after the SSE2 loop, or the whole string without SIMD.
const std::uint64_t hit = ((q - ones) & ~q & high)
                          | ((b - ones) & ~b & high)
                          | ((v - 0x2020202020202020ull) & ~v & high);

The bytes '"' (0x22) and '\\' (0x5C) have no top bit, so the top bits of ~q and ~b are the same as those of ~v. The three masks can therefore be applied once:

const std::uint64_t hit = ((q - ones) | (b - ones) | (v - 0x2020202020202020ull)) & ~v & high;

The result is the same bit for bit, not only the same lowest flagged byte, so the comments about borrows stay true. It saves two ANDs per 8 bytes.

Expected gain

Small and not measured. find_string_delimiter() is the main loop of the simdutf string path, while the plain_output_run() tail runs at most once per string on SIMD builds. As with #6033, Clang may already find this reduction itself and GCC may not, so any gain would show up with GCC first. Checking the generated code (instruction count per word with GCC and Clang) would show whether it is worth a PR.

Tests

A check like the one in #6033, comparing the old and the new mask for random words and for every pair of adjacent byte values (compiled with GCC -O1, since Clang folds the two expressions into one), plus the existing test suite with JSON_USE_SIMDUTF and with JSON_NO_SIMD.

Breaking changes

None. Only the bodies of internal functions would change.

🤖 Generated with Claude Code

Lingua principale
C++
Stelle
50.9k
Fork
7.5k
Merge medio
1g 3h
PR unite (30g)
217

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di nlohmann/json

Tutte le issue di nlohmann/json

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.