This commit is contained in:
nlohmann committed 2026-11-05 15:06:10 +00:00
1 parent 15ab5fa5c1
commit 5531ec9380
7 files changed
+635 -457

No files matched your search

+33 -23
View File
@@ -1,21 +1,21 @@
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 470 516" role="img" aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns="http://www.w3.org/2000/svg">
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 470 620" role="img" aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns="http://www.w3.org/2000/svg">
<title id="nj-charts-ct">Change in compile time against the default configuration at -O0, Apple clang and G&#8203;CC 16</title>
<desc id="nj-charts-ct-d">Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G&#8203;CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G&#8203;CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G&#8203;CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G&#8203;CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G&#8203;CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G&#8203;CC 16 -9 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G&#8203;CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G&#8203;CC 16 -1 %.</desc>
<desc id="nj-charts-ct-d">Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G&#8203;CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G&#8203;CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G&#8203;CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G&#8203;CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G&#8203;CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G&#8203;CC 16 -9 %; JSON_HAS_STD_FORMAT=0 on a model translation unit: Apple clang -1 %, G&#8203;CC 16 -4 %; JSON_HAS_RANGES=0 on a model translation unit: Apple clang -4 %, G&#8203;CC 16 -1 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G&#8203;CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G&#8203;CC 16 -1 %.</desc>
<rect class="nj-charts-clang" x="8" y="10" width="12" height="12" rx="3"/>
<text class="nj-charts-leg" x="26" y="20.5">Apple clang</text>
<rect class="nj-charts-gcc" x="126" y="10" width="12" height="12" rx="3"/>
<text class="nj-charts-leg" x="144" y="20.5">G&#8203;CC 16</text>
<line class="nj-charts-grid" x1="47.4" y1="58" x2="47.4" y2="472"/>
<text class="nj-charts-tick" x="47.4" y="488">&#8722;80 %</text>
<line class="nj-charts-grid" x1="126.2" y1="58" x2="126.2" y2="472"/>
<text class="nj-charts-tick" x="126.2" y="488">&#8722;60 %</text>
<line class="nj-charts-grid" x1="205" y1="58" x2="205" y2="472"/>
<text class="nj-charts-tick" x="205" y="488">&#8722;40 %</text>
<line class="nj-charts-grid" x1="283.8" y1="58" x2="283.8" y2="472"/>
<text class="nj-charts-tick" x="283.8" y="488">&#8722;20 %</text>
<text class="nj-charts-tick" x="362.6" y="488">0 %</text>
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="506">&#8592; faster</text>
<text class="nj-charts-tick nj-charts-tick--r" x="462" y="506">slower &#8594;</text>
<line class="nj-charts-grid" x1="47.4" y1="58" x2="47.4" y2="576"/>
<text class="nj-charts-tick" x="47.4" y="592">&#8722;80 %</text>
<line class="nj-charts-grid" x1="126.2" y1="58" x2="126.2" y2="576"/>
<text class="nj-charts-tick" x="126.2" y="592">&#8722;60 %</text>
<line class="nj-charts-grid" x1="205" y1="58" x2="205" y2="576"/>
<text class="nj-charts-tick" x="205" y="592">&#8722;40 %</text>
<line class="nj-charts-grid" x1="283.8" y1="58" x2="283.8" y2="576"/>
<text class="nj-charts-tick" x="283.8" y="592">&#8722;20 %</text>
<text class="nj-charts-tick" x="362.6" y="592">0 %</text>
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="610">&#8592; faster</text>
<text class="nj-charts-tick nj-charts-tick--r" x="462" y="610">slower &#8594;</text>
<text class="nj-charts-rowlabel" x="8" y="62"><tspan class="nj-charts-code">json_fwd.hpp instead of json.hpp</tspan><tspan class="nj-charts-sub"> &#183; header-only TU</tspan></text>
<path class="nj-charts-clang" d="M362.6 70 H122.32 Q118.32 70 118.32 74 V78 Q118.32 82 122.32 82 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): &#8722;62 %</title></path>
<text class="nj-charts-val" x="367.6" y="80.5">&#8722;62 %</text>
@@ -46,15 +46,25 @@
<text class="nj-charts-val" x="367.6" y="340.5">&#8722;5 %</text>
<path class="nj-charts-gcc" d="M362.6 344 H331.14 Q327.14 344 327.14 348 V352 Q327.14 356 331.14 356 H362.6 Z"><title>JSON_HAS_FILESYSTEM=0, model TU (G&#8203;CC 16): &#8722;9 %</title></path>
<text class="nj-charts-val" x="367.6" y="354.5">&#8722;9 %</text>
<text class="nj-charts-rowlabel" x="8" y="374"><tspan class="nj-charts-code">JSON_NO_IO</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 382 H358.72 Q354.72 382 354.72 386 V390 Q354.72 394 358.72 394 H362.6 Z"><title>JSON_NO_IO, model TU (Apple clang): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="392.5">&#8722;2 %</text>
<path class="nj-charts-gcc" d="M362.6 396 H358.72 Q354.72 396 354.72 400 V404 Q354.72 408 358.72 408 H362.6 Z"><title>JSON_NO_IO, model TU (G&#8203;CC 16): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="406.5">&#8722;2 %</text>
<text class="nj-charts-rowlabel" x="8" y="426"><tspan class="nj-charts-code">JSON_USE_GLOBAL_UDLS=0</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 434 h0.5 v12 h-0.5 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 %</title></path>
<text class="nj-charts-val" x="367.6" y="444.5">0 %</text>
<path class="nj-charts-gcc" d="M362.6 448 H362.6 Q358.66 448 358.66 451.94 V456.06 Q358.66 460 362.6 460 H362.6 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (G&#8203;CC 16): &#8722;1 %</title></path>
<text class="nj-charts-rowlabel" x="8" y="374"><tspan class="nj-charts-code">JSON_HAS_STD_FORMAT=0</tspan><tspan class="nj-charts-sub"> &#183; model TU</tspan></text>
<path class="nj-charts-clang" d="M362.6 382 H362.6 Q358.66 382 358.66 385.94 V390.06 Q358.66 394 362.6 394 H362.6 Z"><title>JSON_HAS_STD_FORMAT=0, model TU (Apple clang): &#8722;1 %</title></path>
<text class="nj-charts-val" x="367.6" y="392.5">&#8722;1 %</text>
<path class="nj-charts-gcc" d="M362.6 396 H350.84 Q346.84 396 346.84 400 V404 Q346.84 408 350.84 408 H362.6 Z"><title>JSON_HAS_STD_FORMAT=0, model TU (G&#8203;CC 16): &#8722;4 %</title></path>
<text class="nj-charts-val" x="367.6" y="406.5">&#8722;4 %</text>
<text class="nj-charts-rowlabel" x="8" y="426"><tspan class="nj-charts-code">JSON_HAS_RANGES=0</tspan><tspan class="nj-charts-sub"> &#183; model TU</tspan></text>
<path class="nj-charts-clang" d="M362.6 434 H350.84 Q346.84 434 346.84 438 V442 Q346.84 446 350.84 446 H362.6 Z"><title>JSON_HAS_RANGES=0, model TU (Apple clang): &#8722;4 %</title></path>
<text class="nj-charts-val" x="367.6" y="444.5">&#8722;4 %</text>
<path class="nj-charts-gcc" d="M362.6 448 H362.6 Q358.66 448 358.66 451.94 V456.06 Q358.66 460 362.6 460 H362.6 Z"><title>JSON_HAS_RANGES=0, model TU (G&#8203;CC 16): &#8722;1 %</title></path>
<text class="nj-charts-val" x="367.6" y="458.5">&#8722;1 %</text>
<line class="nj-charts-zero" x1="362.6" y1="58" x2="362.6" y2="472"/>
<text class="nj-charts-rowlabel" x="8" y="478"><tspan class="nj-charts-code">JSON_NO_IO</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 486 H358.72 Q354.72 486 354.72 490 V494 Q354.72 498 358.72 498 H362.6 Z"><title>JSON_NO_IO, model TU (Apple clang): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="496.5">&#8722;2 %</text>
<path class="nj-charts-gcc" d="M362.6 500 H358.72 Q354.72 500 354.72 504 V508 Q354.72 512 358.72 512 H362.6 Z"><title>JSON_NO_IO, model TU (G&#8203;CC 16): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="510.5">&#8722;2 %</text>
<text class="nj-charts-rowlabel" x="8" y="530"><tspan class="nj-charts-code">JSON_USE_GLOBAL_UDLS=0</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 538 h0.5 v12 h-0.5 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 %</title></path>
<text class="nj-charts-val" x="367.6" y="548.5">0 %</text>
<path class="nj-charts-gcc" d="M362.6 552 H362.6 Q358.66 552 358.66 555.94 V560.06 Q358.66 564 362.6 564 H362.6 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (G&#8203;CC 16): &#8722;1 %</title></path>
<text class="nj-charts-val" x="367.6" y="562.5">&#8722;1 %</text>
<line class="nj-charts-zero" x1="362.6" y1="58" x2="362.6" y2="576"/>
</svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

+124 -24
View File
@@ -11,6 +11,11 @@ that cost, ordered by how much they typically save.
16.2.0 on macOS (Apple M1 Max). All configurations were run interleaved, in alternating order. They show the order
of magnitude to expect; measure your own code before and after a change.
The two sections on `std::format` and ranges apply to C++20 only and were measured with `-std=c++20`, so their
baselines are slower than the others. Their differences are mostly within the run-to-run noise of a few percent:
two complete runs of the same configuration differed by up to 10% in the median. The tables show the later run (one
outlier cell was repeated).
The translation units are listed below. They replace the ones used for earlier versions of this page, whose
sources were not published, so the numbers differ from earlier versions.
@@ -63,24 +68,24 @@ that cost, ordered by how much they typically save.
```
<div class="nj-fig-wrap" markdown>
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 470 516" role="img" aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns="http://www.w3.org/2000/svg">
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 470 620" role="img" aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns="http://www.w3.org/2000/svg">
<title id="nj-charts-ct">Change in compile time against the default configuration at -O0, Apple clang and G&#8203;CC 16</title>
<desc id="nj-charts-ct-d">Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G&#8203;CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G&#8203;CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G&#8203;CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G&#8203;CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G&#8203;CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G&#8203;CC 16 -9 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G&#8203;CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G&#8203;CC 16 -1 %.</desc>
<desc id="nj-charts-ct-d">Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G&#8203;CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G&#8203;CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G&#8203;CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G&#8203;CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G&#8203;CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G&#8203;CC 16 -9 %; JSON_HAS_STD_FORMAT=0 on a model translation unit: Apple clang -1 %, G&#8203;CC 16 -4 %; JSON_HAS_RANGES=0 on a model translation unit: Apple clang -4 %, G&#8203;CC 16 -1 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G&#8203;CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G&#8203;CC 16 -1 %.</desc>
<rect class="nj-charts-clang" x="8" y="10" width="12" height="12" rx="3"/>
<text class="nj-charts-leg" x="26" y="20.5">Apple clang</text>
<rect class="nj-charts-gcc" x="126" y="10" width="12" height="12" rx="3"/>
<text class="nj-charts-leg" x="144" y="20.5">G&#8203;CC 16</text>
<line class="nj-charts-grid" x1="47.4" y1="58" x2="47.4" y2="472"/>
<text class="nj-charts-tick" x="47.4" y="488">&#8722;80 %</text>
<line class="nj-charts-grid" x1="126.2" y1="58" x2="126.2" y2="472"/>
<text class="nj-charts-tick" x="126.2" y="488">&#8722;60 %</text>
<line class="nj-charts-grid" x1="205" y1="58" x2="205" y2="472"/>
<text class="nj-charts-tick" x="205" y="488">&#8722;40 %</text>
<line class="nj-charts-grid" x1="283.8" y1="58" x2="283.8" y2="472"/>
<text class="nj-charts-tick" x="283.8" y="488">&#8722;20 %</text>
<text class="nj-charts-tick" x="362.6" y="488">0 %</text>
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="506">&#8592; faster</text>
<text class="nj-charts-tick nj-charts-tick--r" x="462" y="506">slower &#8594;</text>
<line class="nj-charts-grid" x1="47.4" y1="58" x2="47.4" y2="576"/>
<text class="nj-charts-tick" x="47.4" y="592">&#8722;80 %</text>
<line class="nj-charts-grid" x1="126.2" y1="58" x2="126.2" y2="576"/>
<text class="nj-charts-tick" x="126.2" y="592">&#8722;60 %</text>
<line class="nj-charts-grid" x1="205" y1="58" x2="205" y2="576"/>
<text class="nj-charts-tick" x="205" y="592">&#8722;40 %</text>
<line class="nj-charts-grid" x1="283.8" y1="58" x2="283.8" y2="576"/>
<text class="nj-charts-tick" x="283.8" y="592">&#8722;20 %</text>
<text class="nj-charts-tick" x="362.6" y="592">0 %</text>
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="610">&#8592; faster</text>
<text class="nj-charts-tick nj-charts-tick--r" x="462" y="610">slower &#8594;</text>
<text class="nj-charts-rowlabel" x="8" y="62"><tspan class="nj-charts-code">json_fwd.hpp instead of json.hpp</tspan><tspan class="nj-charts-sub"> &#183; header-only TU</tspan></text>
<path class="nj-charts-clang" d="M362.6 70 H122.32 Q118.32 70 118.32 74 V78 Q118.32 82 122.32 82 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): &#8722;62 %</title></path>
<text class="nj-charts-val" x="367.6" y="80.5">&#8722;62 %</text>
@@ -111,22 +116,33 @@ that cost, ordered by how much they typically save.
<text class="nj-charts-val" x="367.6" y="340.5">&#8722;5 %</text>
<path class="nj-charts-gcc" d="M362.6 344 H331.14 Q327.14 344 327.14 348 V352 Q327.14 356 331.14 356 H362.6 Z"><title>JSON_HAS_FILESYSTEM=0, model TU (G&#8203;CC 16): &#8722;9 %</title></path>
<text class="nj-charts-val" x="367.6" y="354.5">&#8722;9 %</text>
<text class="nj-charts-rowlabel" x="8" y="374"><tspan class="nj-charts-code">JSON_NO_IO</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 382 H358.72 Q354.72 382 354.72 386 V390 Q354.72 394 358.72 394 H362.6 Z"><title>JSON_NO_IO, model TU (Apple clang): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="392.5">&#8722;2 %</text>
<path class="nj-charts-gcc" d="M362.6 396 H358.72 Q354.72 396 354.72 400 V404 Q354.72 408 358.72 408 H362.6 Z"><title>JSON_NO_IO, model TU (G&#8203;CC 16): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="406.5">&#8722;2 %</text>
<text class="nj-charts-rowlabel" x="8" y="426"><tspan class="nj-charts-code">JSON_USE_GLOBAL_UDLS=0</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 434 h0.5 v12 h-0.5 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 %</title></path>
<text class="nj-charts-val" x="367.6" y="444.5">0 %</text>
<path class="nj-charts-gcc" d="M362.6 448 H362.6 Q358.66 448 358.66 451.94 V456.06 Q358.66 460 362.6 460 H362.6 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (G&#8203;CC 16): &#8722;1 %</title></path>
<text class="nj-charts-rowlabel" x="8" y="374"><tspan class="nj-charts-code">JSON_HAS_STD_FORMAT=0</tspan><tspan class="nj-charts-sub"> &#183; model TU</tspan></text>
<path class="nj-charts-clang" d="M362.6 382 H362.6 Q358.66 382 358.66 385.94 V390.06 Q358.66 394 362.6 394 H362.6 Z"><title>JSON_HAS_STD_FORMAT=0, model TU (Apple clang): &#8722;1 %</title></path>
<text class="nj-charts-val" x="367.6" y="392.5">&#8722;1 %</text>
<path class="nj-charts-gcc" d="M362.6 396 H350.84 Q346.84 396 346.84 400 V404 Q346.84 408 350.84 408 H362.6 Z"><title>JSON_HAS_STD_FORMAT=0, model TU (G&#8203;CC 16): &#8722;4 %</title></path>
<text class="nj-charts-val" x="367.6" y="406.5">&#8722;4 %</text>
<text class="nj-charts-rowlabel" x="8" y="426"><tspan class="nj-charts-code">JSON_HAS_RANGES=0</tspan><tspan class="nj-charts-sub"> &#183; model TU</tspan></text>
<path class="nj-charts-clang" d="M362.6 434 H350.84 Q346.84 434 346.84 438 V442 Q346.84 446 350.84 446 H362.6 Z"><title>JSON_HAS_RANGES=0, model TU (Apple clang): &#8722;4 %</title></path>
<text class="nj-charts-val" x="367.6" y="444.5">&#8722;4 %</text>
<path class="nj-charts-gcc" d="M362.6 448 H362.6 Q358.66 448 358.66 451.94 V456.06 Q358.66 460 362.6 460 H362.6 Z"><title>JSON_HAS_RANGES=0, model TU (G&#8203;CC 16): &#8722;1 %</title></path>
<text class="nj-charts-val" x="367.6" y="458.5">&#8722;1 %</text>
<line class="nj-charts-zero" x1="362.6" y1="58" x2="362.6" y2="472"/>
<text class="nj-charts-rowlabel" x="8" y="478"><tspan class="nj-charts-code">JSON_NO_IO</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 486 H358.72 Q354.72 486 354.72 490 V494 Q354.72 498 358.72 498 H362.6 Z"><title>JSON_NO_IO, model TU (Apple clang): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="496.5">&#8722;2 %</text>
<path class="nj-charts-gcc" d="M362.6 500 H358.72 Q354.72 500 354.72 504 V508 Q354.72 512 358.72 512 H362.6 Z"><title>JSON_NO_IO, model TU (G&#8203;CC 16): &#8722;2 %</title></path>
<text class="nj-charts-val" x="367.6" y="510.5">&#8722;2 %</text>
<text class="nj-charts-rowlabel" x="8" y="530"><tspan class="nj-charts-code">JSON_USE_GLOBAL_UDLS=0</tspan><tspan class="nj-charts-sub"> &#183; model TU*</tspan></text>
<path class="nj-charts-clang" d="M362.6 538 h0.5 v12 h-0.5 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 %</title></path>
<text class="nj-charts-val" x="367.6" y="548.5">0 %</text>
<path class="nj-charts-gcc" d="M362.6 552 H362.6 Q358.66 552 358.66 555.94 V560.06 Q358.66 564 362.6 564 H362.6 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (G&#8203;CC 16): &#8722;1 %</title></path>
<text class="nj-charts-val" x="367.6" y="562.5">&#8722;1 %</text>
<line class="nj-charts-zero" x1="362.6" y1="58" x2="362.6" y2="576"/>
</svg>
</div>
<p class="nj-charts-caption" markdown>Change in compile time at `-O0` against the default configuration of the same
translation unit, taken from the tables below (medians of nine runs, see above). * computed from the milliseconds in
translation unit, taken from the tables below (medians of nine runs, see above; the `std::format` and ranges rows are
measured with `-std=c++20`). * computed from the milliseconds in
[Options without effect on compile times](#options-without-effect-on-compile-times).</p>
## Include `json_fwd.hpp` in headers
@@ -274,6 +290,88 @@ from and to `std::string`; whether that fallback exists depends on the platform'
(`std::wstring` on Windows), so check code that converts paths. `JSON_NO_IO` additionally removes all stream
functions (see [Options without effect](#options-without-effect-on-compile-times)).
## Switch off `std::format` support
With C++20 and a standard library that provides `<format>`, the library includes it to provide a
[`std::formatter<basic_json>`](../api/basic_json/std_formatter.md) specialization (see
[`JSON_HAS_STD_FORMAT`](../api/macros/json_has_std_format.md)). If you do not format JSON values with `std::format`,
switch the detection off for the whole project:
```cmake
target_compile_definitions(my_target PRIVATE JSON_HAS_STD_FORMAT=0)
```
| Compiler | Translation unit | Default (`-O0` / `-O2`) | `std::format` off (`-O0` / `-O2`) | Change |
|-------------|------------------|------------------------:|----------------------------------:|-----------:|
| Apple clang | model | 1283 ms / 1544 ms | 1269 ms / 1539 ms | −1% / 0% |
| GCC 16 | model | 2026 ms / 2482 ms | 1944 ms / 2416 ms | −4% / −3% |
| Apple clang | parsing | 1350 ms / 2278 ms | 1347 ms / 2300 ms | 0% / +1% |
| GCC 16 | parsing | 2715 ms / 4351 ms | 2644 ms / 4287 ms | −3% / −1% |
<p class="nj-table-caption" markdown>Compile time with `JSON_HAS_STD_FORMAT=0` against the default configuration, both with `-std=c++20`, at `-O0` and `-O2`.</p>
The saving is small, and only GCC shows it: libstdc++'s `<format>` is an additional header that nothing else in the
translation unit includes, so the macro removes it (and the headers it pulls in). With libc++ (Apple clang), other
standard headers include `<format>` anyway, so the macro only removes the library's own formatter, and the difference is
within the noise.
The trade-off: the `std::formatter<basic_json>` specialization is removed, so `#!cpp std::format("{}", j)`,
and `#!cpp std::format_to` with a JSON value no longer compile (in a test with both compilers on
macOS, the error was that `std::formatter` must be specialized for the type). Use [`dump()`](../api/basic_json/dump.md),
or the stream operators, instead.
## Switch off ranges support
With C++20 and a standard library that provides `<ranges>`, the library includes it to declare the
[`items()`](../api/basic_json/items.md) proxy a *borrowed range*, and uses the `std::ranges` concepts and algorithms for
construction from range views and for iterator input (see [`JSON_HAS_RANGES`](../api/macros/json_has_ranges.md)). If you
do not need these, switch the detection off for the whole project:
```cmake
target_compile_definitions(my_target PRIVATE JSON_HAS_RANGES=0)
```
| Compiler | Translation unit | Default (`-O0` / `-O2`) | Ranges off (`-O0` / `-O2`) | Change |
|-------------|------------------|------------------------:|---------------------------:|-----------:|
| Apple clang | model | 1283 ms / 1544 ms | 1237 ms / 1495 ms | −4% / −3% |
| GCC 16 | model | 2026 ms / 2482 ms | 2004 ms / 2464 ms | −1% / −1% |
| Apple clang | parsing | 1350 ms / 2278 ms | 1311 ms / 2284 ms | −3% / 0% |
| GCC 16 | parsing | 2715 ms / 4351 ms | 2705 ms / 4427 ms | 0% / +2% |
<p class="nj-table-caption" markdown>Compile time with `JSON_HAS_RANGES=0` against the default configuration, both with `-std=c++20`, at `-O0` and `-O2`.</p>
The saving is small as well, and with GCC it is not distinguishable from the noise: its `<format>` includes `<span>`,
so with `std::format` support left on, part of the ranges machinery is still parsed.
Both macros together save more than either alone:
```cmake
target_compile_definitions(my_target PRIVATE JSON_HAS_STD_FORMAT=0 JSON_HAS_RANGES=0)
```
| Compiler | Translation unit | Default (`-O0` / `-O2`) | Both off (`-O0` / `-O2`) | Change |
|-------------|------------------|------------------------:|-------------------------:|-----------:|
| Apple clang | model | 1283 ms / 1544 ms | 1223 ms / 1504 ms | −5% / −3% |
| GCC 16 | model | 2026 ms / 2482 ms | 1914 ms / 2378 ms | −6% / −4% |
| Apple clang | parsing | 1350 ms / 2278 ms | 1311 ms / 2271 ms | −3% / 0% |
| GCC 16 | parsing | 2715 ms / 4351 ms | 2635 ms / 4260 ms | −3% / −2% |
<p class="nj-table-caption" markdown>Compile time with `JSON_HAS_STD_FORMAT=0` and `JSON_HAS_RANGES=0` against the default configuration, both with `-std=c++20`, at `-O0` and `-O2`.</p>
The trade-offs of `JSON_HAS_RANGES=0` are larger than those of the other options on this page:
- `items()` is no longer a borrowed range. On a temporary, `#!cpp std::ranges::begin(make_json().items())` no longer
compiles, and `std::ranges` algorithms such as `#!cpp std::ranges::find_if(make_json().items(), pred)` return
`std::ranges::dangling` instead of an iterator, so code that uses the result no longer compiles. Calling them on
`#!cpp j.items()` for a named `j` is not affected.
- [`JSON_HAS_RANGE_VIEW_CONVERSION`](../api/macros/json_has_range_view_conversion.md) becomes `0`, so a JSON array can no
longer be constructed from a `std::ranges::view` such as the result of `std::views::filter`. The assignment
`#!cpp json j = v | std::views::filter(pred);` no longer compiles.
- Parsing from an iterator pair loses the C++20 fast path for contiguous iterators that are not pointers (for
example those of `std::vector`) and falls back to byte-at-a-time scanning. The result is the same; parsing may be
slower (not measured here).
The first two were checked with both compilers on macOS; the third is read from the library's source.
## Use C++20 modules
With a toolchain that supports named modules, `import nlohmann.json;` compiles the library once into a module and
@@ -463,6 +561,8 @@ and −2% / 0% (GCC). To get a saving, combine it with
- [`JSON_HAS_FILESYSTEM`](../api/macros/json_has_filesystem.md) - control the conversions from and to
`std::filesystem::path`
- [`JSON_HAS_STD_FORMAT`](../api/macros/json_has_std_format.md) - control the `std::formatter` specialization
- [`JSON_HAS_RANGES`](../api/macros/json_has_ranges.md) - control the use of `std::ranges`
- [`JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md) - do not include the user-defined string
literals automatically
- [Modules](../features/modules.md) - C++20 module support
+7 -4
View File
@@ -1,4 +1,4 @@
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="JSON for Modern C++ is a header-only C++11 library that makes JSON a first-class data type."><meta name=author content="Niels Lohmann"><link href="https://json.nlohmann.me/integration/compile_times/" rel="canonical"><link href=../pkg-config/ rel=prev><link href=../../api/basic_json/ rel=next><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.8.0"><title>Compile times - JSON for Modern C++</title><link rel=stylesheet href=../../assets/stylesheets/main.57a0d79d.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.fb2fffe2.min.css><link rel=stylesheet href=../../css/custom.css><link rel=stylesheet href=../../css/brand.css><link rel=stylesheet href=../../css/fig-sax.css><link rel=stylesheet href=../../css/fig-jsonview.css><link rel=stylesheet href=../../css/fig-exceptions.css><link rel=stylesheet href=../../css/fig-pointer.css><link rel=stylesheet href=../../css/fig-charts.css><link rel=stylesheet href=../../css/fig-integration.css><link rel=stylesheet href=../../css/fig-macros.css><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=custom data-md-color-accent=custom> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#compile-times class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="JSON for Modern C++" class="md-header__button md-logo" aria-label="JSON for Modern C++" data-md-component=logo> <img src=../../images/wordmark-header.svg alt=logo> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> JSON for Modern C++ </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Compile times </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme=default data-md-color-primary=custom data-md-color-accent=custom aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> <input class=md-option data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme=slate data-md-color-primary=custom data-md-color-accent=custom aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.Line truncated
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="JSON for Modern C++ is a header-only C++11 library that makes JSON a first-class data type."><meta name=author content="Niels Lohmann"><link href="https://json.nlohmann.me/integration/compile_times/" rel="canonical"><link href=../pkg-config/ rel=prev><link href=../../api/basic_json/ rel=next><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.8.0"><title>Compile times - JSON for Modern C++</title><link rel=stylesheet href=../../assets/stylesheets/main.57a0d79d.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.fb2fffe2.min.css><link rel=stylesheet href=../../css/custom.css><link rel=stylesheet href=../../css/brand.css><link rel=stylesheet href=../../css/fig-sax.css><link rel=stylesheet href=../../css/fig-jsonview.css><link rel=stylesheet href=../../css/fig-exceptions.css><link rel=stylesheet href=../../css/fig-pointer.css><link rel=stylesheet href=../../css/fig-charts.css><link rel=stylesheet href=../../css/fig-integration.css><link rel=stylesheet href=../../css/fig-macros.css><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=custom data-md-color-accent=custom> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#compile-times class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="JSON for Modern C++" class="md-header__button md-logo" aria-label="JSON for Modern C++" data-md-component=logo> <img src=../../images/wordmark-header.svg alt=logo> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> JSON for Modern C++ </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Compile times </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme=default data-md-color-primary=custom data-md-color-accent=custom aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> <input class=md-option data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme=slate data-md-color-primary=custom data-md-color-accent=custom aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.Line truncated
<span class=p>{</span>
<span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>string</span><span class=w> </span><span class=n>name</span><span class=p>;</span>
<span class=w> </span><span class=kt>int</span><span class=w> </span><span class=n>age</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=mi>0</span><span class=p>;</span>
@@ -32,7 +32,7 @@
<span class=k>struct</span><span class=w> </span><span class=nc>person</span><span class=p>;</span>
<span class=kt>void</span><span class=w> </span><span class=nf>to_json</span><span class=p>(</span><span class=n>nlohmann</span><span class=o>::</span><span class=n>json</span><span class=o>&amp;</span><span class=w> </span><span class=n>j</span><span class=p>,</span><span class=w> </span><span class=k>const</span><span class=w> </span><span class=n>person</span><span class=o>&amp;</span><span class=w> </span><span class=n>p</span><span class=p>);</span>
<span class=kt>void</span><span class=w> </span><span class=nf>from_json</span><span class=p>(</span><span class=k>const</span><span class=w> </span><span class=n>nlohmann</span><span class=o>::</span><span class=n>json</span><span class=o>&amp;</span><span class=w> </span><span class=n>j</span><span class=p>,</span><span class=w> </span><span class=n>person</span><span class=o>&amp;</span><span class=w> </span><span class=n>p</span><span class=p>);</span>
</code></pre></div> </details> <div class=nj-fig-wrap> <p><svg class="nj-fig nj-charts nj-charts--compile" viewbox="0 0 470 516" role=img aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns=http://www.w3.org/2000/svg> <title id=nj-charts-ct>Change in compile time against the default configuration at -O0, Apple clang and G&#8203;CC 16</title> <desc id=nj-charts-ct-d>Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G&#8203;CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G&#8203;CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G&#8203;CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G&#8203;CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G&#8203;CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G&#8203;CC 16 -9 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G&#8203;CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G&#8203;CC 16 -1 %.</desc> <rect class=nj-charts-clang x=8 y=10 width=12 height=12 rx=3 /> <text class=nj-charts-leg x=26 y=20.5>Apple clang</text> <rect class=nj-charts-gcc x=126 y=10 width=12 height=12 rx=3 /> <text class=nj-charts-leg x=144 y=20.5>G&#8203;CC 16</text> <line class=nj-charts-grid x1=47.4 y1=58 x2=47.4 y2=472 /> <text class=nj-charts-tick x=47.4 y=488>&#8722;80 %</text> <line class=nj-charts-grid x1=126.2 y1=58 x2=126.2 y2=472 /> <text class=nj-charts-tick x=126.2 y=488>&#8722;60 %</text> <line class=nj-charts-grid x1=205 y1=58 x2=205 y2=472 /> <text class=nj-charts-tick x=205 y=488>&#8722;40 %</text> <line class=nj-charts-grid x1=283.8 y1=58 x2=283.8 y2=472 /> <text class=nj-charts-tick x=283.8 y=488>&#8722;20 %</text> <text class=nj-charts-tick x=362.6 y=488>0 %</text> <text class="nj-charts-tick nj-charts-tick--l" x=8 y=506>&#8592; faster</text> <text class="nj-charts-tick nj-charts-tick--r" x=462 y=506>slower &#8594;</text> <text class=nj-charts-rowlabel x=8 y=62><tspan class=nj-charts-code>json_fwd.hpp instead of json.hpp</tspan><tspan class=nj-charts-sub> &#183; header-only TU</tspan></text> <path class=nj-charts-clang d="M362.6 70 H122.32 Q118.32 70 118.32 74 V78 Q118.32 82 122.32 82 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): &#8722;62 %</title></path> <text class=nj-charts-val x=367.6 y=80.5>&#8722;62 %</text> <path class=nj-charts-gcc d="M362.6 84 H43.52 Q39.52 84 39.52 88 V92 Q39.52 96 43.52 96 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (G&#8203;CC 16): &#8722;82 %</title></path> <text class=nj-charts-val x=367.6 y=94.5>&#8722;82 %</text> <text class=nj-charts-rowlabel x=8 y=114><tspan class=nj-charts-code>extern template</tspan><tspan class=nj-charts-sub> &#183; parsing TU</tspan></text> <path class=nj-charts-clang d="M362.6 122 H339.02 Q335.02 122 335.02 126 V130 Q335.02 134 339.02 134 H362.6 Z"><title>extern template, parsing TU (Apple clang): &#8722;7 %</title></path> <text class=nj-charts-val x=367.6 y=132.5>&#8722;7 %</text> <path class=nj-charts-gcc d="M362.6 136 H283.86 Q279.86 136 279.86 140 V144 Q279.86 148 283.86 148 H362.6 Z"><title>extern template, parsing TU (G&#8203;CC 16): &#8722;21 %</title></path> <text class=nj-charts-val x=367.6 y=146.5>&#8722;21 %</text> <text class=nj-charts-rowlabel x=8 y=166><tspan class=nj-charts-code>JSON_NO_AUTOMATIC_UDLS</tspan><tspan class=nj-charts-sub> &#183; model TU</tspan></text> <path class=nj-charts-clang d="M362.6 174 H323.26 Q319.26 174 319.26 178 V182 Q319.26 186 323.26 186 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, model TU (Apple clang): &#8722;11 %</title></path> <text class=nj-charts-val x=367.6 y=184.5>&#8722;11 %</text> <path class=nj-charts-gcc d="M362.6 188 H323.26 Q319.26 188 319.26 192 V196 Q319.26 200 323.26 200 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, model TU (G&#8203;CC 16): &#8722;11 %</title></path> <text class=nj-charts-val x=367.6 y=198.5>&#8722;11 %</text> <text class=nj-charts-rowlabel x=8 y=218><tspan class=nj-charts-code>JSON_NO_AUTOMATIC_UDLS</tspan><tspan class=nj-charts-sub> &#183; parsing TU</tspan></text> <path class=nj-charts-clang d="M362.6 226 H362.6 Q358.66 226 358.66 229.94 V234.06 Q358.66 238 362.6 238 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, parsing TU (Apple clang): &#8722;1 %</title></path> <text class=nj-charts-val x=367.6 y=236.5>&#8722;1 %</text> <path class=nj-charts-gcc d="M362.6 240 H358.72 Q354.72 240 354.72 244 V248 Q354.72 252 358.72 252 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, parsing TU (G&#8203;CC 16): &#8722;2 %</title></path> <text class=nj-charts-val x=367.6 y=250.5>&#8722;2 %</text> <text class=nj-charts-rowlabel x=8 y=270><tspan class=nj-charts-code>JSON_HAS_FILESYSTEM=0 + JSON_NO_IO</tspan><tspan class=nj-charts-sub> &#183; model TU</tspan></text> <path class=nj-charts-clang d="M362.6 278 H335.08 Q331.08 2Line truncated
</code></pre></div> </details> <div class=nj-fig-wrap> <p><svg class="nj-fig nj-charts nj-charts--compile" viewbox="0 0 470 620" role=img aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns=http://www.w3.org/2000/svg> <title id=nj-charts-ct>Change in compile time against the default configuration at -O0, Apple clang and G&#8203;CC 16</title> <desc id=nj-charts-ct-d>Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G&#8203;CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G&#8203;CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G&#8203;CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G&#8203;CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G&#8203;CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G&#8203;CC 16 -9 %; JSON_HAS_STD_FORMAT=0 on a model translation unit: Apple clang -1 %, G&#8203;CC 16 -4 %; JSON_HAS_RANGES=0 on a model translation unit: Apple clang -4 %, G&#8203;CC 16 -1 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G&#8203;CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G&#8203;CC 16 -1 %.</desc> <rect class=nj-charts-clang x=8 y=10 width=12 height=12 rx=3 /> <text class=nj-charts-leg x=26 y=20.5>Apple clang</text> <rect class=nj-charts-gcc x=126 y=10 width=12 height=12 rx=3 /> <text class=nj-charts-leg x=144 y=20.5>G&#8203;CC 16</text> <line class=nj-charts-grid x1=47.4 y1=58 x2=47.4 y2=576 /> <text class=nj-charts-tick x=47.4 y=592>&#8722;80 %</text> <line class=nj-charts-grid x1=126.2 y1=58 x2=126.2 y2=576 /> <text class=nj-charts-tick x=126.2 y=592>&#8722;60 %</text> <line class=nj-charts-grid x1=205 y1=58 x2=205 y2=576 /> <text class=nj-charts-tick x=205 y=592>&#8722;40 %</text> <line class=nj-charts-grid x1=283.8 y1=58 x2=283.8 y2=576 /> <text class=nj-charts-tick x=283.8 y=592>&#8722;20 %</text> <text class=nj-charts-tick x=362.6 y=592>0 %</text> <text class="nj-charts-tick nj-charts-tick--l" x=8 y=610>&#8592; faster</text> <text class="nj-charts-tick nj-charts-tick--r" x=462 y=610>slower &#8594;</text> <text class=nj-charts-rowlabel x=8 y=62><tspan class=nj-charts-code>json_fwd.hpp instead of json.hpp</tspan><tspan class=nj-charts-sub> &#183; header-only TU</tspan></text> <path class=nj-charts-clang d="M362.6 70 H122.32 Q118.32 70 118.32 74 V78 Q118.32 82 122.32 82 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): &#8722;62 %</title></path> <text class=nj-charts-val x=367.6 y=80.5>&#8722;62 %</text> <path class=nj-charts-gcc d="M362.6 84 H43.52 Q39.52 84 39.52 88 V92 Q39.52 96 43.52 96 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (G&#8203;CC 16): &#8722;82 %</title></path> <text class=nj-charts-val x=367.6 y=94.5>&#8722;82 %</text> <text class=nj-charts-rowlabel x=8 y=114><tspan class=nj-charts-code>extern template</tspan><tspan class=nj-charts-sub> &#183; parsing TU</tspan></text> <path class=nj-charts-clang d="M362.6 122 H339.02 Q335.02 122 335.02 126 V130 Q335.02 134 339.02 134 H362.6 Z"><title>extern template, parsing TU (Apple clang): &#8722;7 %</title></path> <text class=nj-charts-val x=367.6 y=132.5>&#8722;7 %</text> <path class=nj-charts-gcc d="M362.6 136 H283.86 Q279.86 136 279.86 140 V144 Q279.86 148 283.86 148 H362.6 Z"><title>extern template, parsing TU (G&#8203;CC 16): &#8722;21 %</title></path> <text class=nj-charts-val x=367.6 y=146.5>&#8722;21 %</text> <text class=nj-charts-rowlabel x=8 y=166><tspan class=nj-charts-code>JSON_NO_AUTOMATIC_UDLS</tspan><tspan class=nj-charts-sub> &#183; model TU</tspan></text> <path class=nj-charts-clang d="M362.6 174 H323.26 Q319.26 174 319.26 178 V182 Q319.26 186 323.26 186 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, model TU (Apple clang): &#8722;11 %</title></path> <text class=nj-charts-val x=367.6 y=184.5>&#8722;11 %</text> <path class=nj-charts-gcc d="M362.6 188 H323.26 Q319.26 188 319.26 192 V196 Q319.26 200 323.26 200 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, model TU (G&#8203;CC 16): &#8722;11 %</title></path> <text class=nj-charts-val x=367.6 y=198.5>&#8722;11 %</text> <text class=nj-charts-rowlabel x=8 y=218><tspan class=nj-charts-code>JSON_NO_AUTOMATIC_UDLS</tspan><tspan class=nj-charts-sub> &#183; parsing TU</tspan></text> <path class=nj-charts-clang d="M362.6 226 H362.6 Q358.66 226 358.66 229.94 V234.06 Q358.66 238 362.6 238 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, parsing TU (Apple clang): &#8722;1 %</title></path> <text class=nj-charts-val x=367.6 y=236.5>&#8722;1 %</text> <path class=nj-charts-gcc d="M362.6 240 H358.72 Q354.72 240 354.72 244 V248 Q354.72 252 358.72 252 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, parsing TU (G&#8203;CC 16): &#8722;2 %</title></path> <text class=nj-charts-val x=367.6 y=250.5>&#8722;2 %</text> <text class=nj-charts-rowlabel x=8 y=270><tspan class=nLine truncated
<span class=cp>#include</span><span class=w> </span><span class=cpf>&lt;nlohmann/json_fwd.hpp&gt;</span>
<span class=k>struct</span><span class=w> </span><span class=nc>person</span><span class=p>;</span>
@@ -53,7 +53,10 @@
<span class=k>template</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>nlohmann</span><span class=o>::</span><span class=n>basic_json</span><span class=o>&lt;&gt;</span><span class=p>;</span>
</code></pre></div> <p>Include <code>json_instance.hpp</code> instead of <code>&lt;nlohmann/json.hpp&gt;</code> and compile and link <code>json_instance.cpp</code> once.</p> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;"><code>extern template</code> (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1157 ms / 2016 ms</td> <td style="text-align: right;">1071 ms / 1844 ms</td> <td style="text-align: right;">−7% / −9%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2529 ms / 4087 ms</td> <td style="text-align: right;">1994 ms / 3190 ms</td> <td style="text-align: right;">−21% / −22%</td> </tr> <tr> <td>Apple clang</td> <td><code>json_instance.cpp</code></td> <td style="text-align: right;">—</td> <td style="text-align: right;">2573 ms / 6221 ms</td> <td style="text-align: right;">—</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td><code>json_instance.cpp</code></td> <td style="text-align: right;">—</td> <td style="text-align: right;">6489 ms / 13759 ms</td> <td style="text-align: right;">—</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time of the parsing translation unit without and with the <code>extern template</code> declaration, at <code>-O0</code> and <code>-O2</code>. The <code>json_instance.cpp</code> rows are the one-off cost of the translation unit that holds the instantiation.</p> <p>Notes:</p> <ul> <li>The saving grows with the number of translation units that use <code>json</code>, while the instantiation translation unit is compiled only once (and is rarely recompiled, as it does not depend on your code).</li> <li>Member function templates (such as <code>get&lt;T&gt;()</code>, <code>parse(InputType&amp;&amp;)</code>, or <code>value(key, default)</code>) are not covered by the explicit instantiation and are still instantiated where they are used.</li> <li>The declaration covers exactly <code>nlohmann::json</code>. Add the same lines for <code>nlohmann::ordered_json</code> (<code>nlohmann::basic_json&lt;nlohmann::ordered_map&gt;</code>) or your own <code>basic_json</code> specializations if you use them.</li> </ul> <h2 id=switch-off-filesystem-support>Switch off filesystem support<a class=headerlink href=#switch-off-filesystem-support title="Permanent link">&para;</a></h2> <p>With C++17, the library includes <code>&lt;filesystem&gt;</code> to provide conversions from and to <code>std::filesystem::path</code> (see <a href=../../api/macros/json_has_filesystem/ ><code>JSON_HAS_FILESYSTEM</code></a>). Parsing <code>&lt;filesystem&gt;</code> is a fixed cost in every translation unit, and it also pulls in <code>&lt;iomanip&gt;</code>, <code>&lt;istream&gt;</code>, and <code>&lt;ostream&gt;</code> (and, with <abbr title="GNU Compiler Collection">GCC</abbr>'s libstdc++, <code>&lt;sstream&gt;</code>). If you do not convert paths, switch the detection off for the whole project:</p> <div class=highlight><pre><span></span><code><span class=nb>target_compile_definitions</span><span class=p>(</span><span class=s>my_target</span><span class=w> </span><span class=s>PRIVATE</span><span class=w> </span><span class=s>JSON_HAS_FILESYSTEM=0</span><span class=w> </span><span class=s>JSON_HAS_EXPERIMENTAL_FILESYSTEM=0</span><span class=p>)</span>
</code></pre></div> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Filesystem off (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1051 ms / 1300 ms</td> <td style="text-align: right;">998 ms / 1257 ms</td> <td style="text-align: right;">−5% / −3%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">1801 ms / 2106 ms</td> <td style="text-align: right;">1636 ms / 2008 ms</td> <td style="text-align: right;">−9% / −5%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1157 ms / 2016 ms</td> <td style="text-align: right;">1107 ms / 1971 ms</td> <td style="text-align: right;">−4% / −2%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2529 ms / 4087 ms</td> <td style="text-align: right;">2405 ms / 4029 ms</td> <td style="text-align: right;">−5% / −1%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with <code>JSON_HAS_FILESYSTEM=0</code> and <code>JSON_HAS_EXPERIMENTAL_FILESYSTEM=0</code> against the default configuration, at <code>-O0</code> and <code>-O2</code>.</p> <p>Only with filesystem support switched off does <a href=../../api/macros/json_no_io/ ><code>JSON_NO_IO</code></a> remove the stream headers from the translation unit, so the two macros save most together:</p> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Filesystem off and <code>JSON_NO_IO</code> (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1051 ms / 1300 ms</td> <td style="text-align: right;">969 ms / 1219 ms</td> <td style="text-align: right;">−8% / −6%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">1801 ms / 2106 ms</td> <td style="text-align: right;">1605 ms / 1982 ms</td> <td style="text-align: right;">−11% / −6%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1157 ms / 2016 ms</td> <td style="text-align: right;">1083 ms / 1947 ms</td> <td style="text-align: right;">−6% / −3%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2529 ms / 4087 ms</td> <td style="text-align: right;">2384 ms / 3972 ms</td> <td style="text-align: right;">−6% / −3%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with filesystem support switched off and <code>JSON_NO_IO</code> defined, against the default configuration, at <code>-O0</code> and <code>-O2</code>.</p> <p>The trade-off: the library's own <code>to_json</code>/<code>from_json</code> overloads for <code>std::filesystem::path</code> (which store the path as <abbr title="Unicode Transformation Format">UTF</abbr>-8) are removed. In a test with both compilers on macOS, paths still converted through their implicit conversion from and to <code>std::string</code>; whether that fallback exists depends on the platform's native path string type (<code>std::wstring</code> on Windows), so check code that converts paths. <code>JSON_NO_IO</code> additionally removes all stream functions (see <a href=#options-without-effect-on-compile-times>Options without effect</a>).</p> <h2 id=use-c20-modules>Use C++20 modules<a class=headerlink href=#use-c20-modules title="Permanent link">&para;</a></h2> <p>With a toolchain that supports named modules, <code>import nlohmann.json;</code> compiles the library once into a module and avoids parsing the header in every translation unit. See <a href=../../features/modules/ >Modules</a> for requirements and known issues. Module support is experimental and currently depends heavily on the compiler version.</p> <div class=nj-fig-wrap> <p><svg class="nj-fig nj-charts nj-charts--compile" viewbox="0 0 440 282" role=img aria-labelledby="nj-charts-mod nj-charts-mod-d" xmlns=http://www.w3.org/2000/svg> <title id=nj-charts-mod>Compile time per translation unit with import nlohmann.json at -O0, and the one-off cost of the module</title> <desc id=nj-charts-mod-d>Horizontal bars, negative is faster, medians of nine runs, -std=c++20 for both. model TU, Apple clang: -48 % (1311 ms to 680 ms); model TU, G&#8203;CC 16: -47 % (2156 ms to 1153 ms); parsing TU, Apple clang: -42 % (1387 ms to 800 ms); parsing TU, G&#8203;CC 16: -36 % (2838 ms to 1810 ms); one-off build, Apple clang: 1630 ms; one-off build, G&#8203;CC 16: 2538 ms.</desc> <rect class=nj-charts-cLine truncated
</code></pre></div> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Filesystem off (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1051 ms / 1300 ms</td> <td style="text-align: right;">998 ms / 1257 ms</td> <td style="text-align: right;">−5% / −3%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">1801 ms / 2106 ms</td> <td style="text-align: right;">1636 ms / 2008 ms</td> <td style="text-align: right;">−9% / −5%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1157 ms / 2016 ms</td> <td style="text-align: right;">1107 ms / 1971 ms</td> <td style="text-align: right;">−4% / −2%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2529 ms / 4087 ms</td> <td style="text-align: right;">2405 ms / 4029 ms</td> <td style="text-align: right;">−5% / −1%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with <code>JSON_HAS_FILESYSTEM=0</code> and <code>JSON_HAS_EXPERIMENTAL_FILESYSTEM=0</code> against the default configuration, at <code>-O0</code> and <code>-O2</code>.</p> <p>Only with filesystem support switched off does <a href=../../api/macros/json_no_io/ ><code>JSON_NO_IO</code></a> remove the stream headers from the translation unit, so the two macros save most together:</p> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Filesystem off and <code>JSON_NO_IO</code> (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1051 ms / 1300 ms</td> <td style="text-align: right;">969 ms / 1219 ms</td> <td style="text-align: right;">−8% / −6%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">1801 ms / 2106 ms</td> <td style="text-align: right;">1605 ms / 1982 ms</td> <td style="text-align: right;">−11% / −6%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1157 ms / 2016 ms</td> <td style="text-align: right;">1083 ms / 1947 ms</td> <td style="text-align: right;">−6% / −3%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2529 ms / 4087 ms</td> <td style="text-align: right;">2384 ms / 3972 ms</td> <td style="text-align: right;">−6% / −3%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with filesystem support switched off and <code>JSON_NO_IO</code> defined, against the default configuration, at <code>-O0</code> and <code>-O2</code>.</p> <p>The trade-off: the library's own <code>to_json</code>/<code>from_json</code> overloads for <code>std::filesystem::path</code> (which store the path as <abbr title="Unicode Transformation Format">UTF</abbr>-8) are removed. In a test with both compilers on macOS, paths still converted through their implicit conversion from and to <code>std::string</code>; whether that fallback exists depends on the platform's native path string type (<code>std::wstring</code> on Windows), so check code that converts paths. <code>JSON_NO_IO</code> additionally removes all stream functions (see <a href=#options-without-effect-on-compile-times>Options without effect</a>).</p> <h2 id=switch-off-stdformat-support>Switch off <code>std::format</code> support<a class=headerlink href=#switch-off-stdformat-support title="Permanent link">&para;</a></h2> <p>With C++20 and a standard library that provides <code>&lt;format&gt;</code>, the library includes it to provide a <a href=../../api/basic_json/std_formatter/ ><code>std::formatter&lt;basic_json&gt;</code></a> specialization (see <a href=../../api/macros/json_has_std_format/ ><code>JSON_HAS_STD_FORMAT</code></a>). If you do not format <abbr title="JavaScript Object Notation">JSON</abbr> values with <code>std::format</code>, switch the detection off for the whole project:</p> <div class=highlight><pre><span></span><code><span class=nb>target_compile_definitions</span><span class=p>(</span><span class=s>my_target</span><span class=w> </span><span class=s>PRIVATE</span><span class=w> </span><span class=s>JSON_HAS_STD_FORMAT=0</span><span class=p>)</span>
</code></pre></div> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;"><code>std::format</code> off (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1283 ms / 1544 ms</td> <td style="text-align: right;">1269 ms / 1539 ms</td> <td style="text-align: right;">−1% / 0%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">2026 ms / 2482 ms</td> <td style="text-align: right;">1944 ms / 2416 ms</td> <td style="text-align: right;">−4% / −3%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1350 ms / 2278 ms</td> <td style="text-align: right;">1347 ms / 2300 ms</td> <td style="text-align: right;">0% / +1%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2715 ms / 4351 ms</td> <td style="text-align: right;">2644 ms / 4287 ms</td> <td style="text-align: right;">−3% / −1%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with <code>JSON_HAS_STD_FORMAT=0</code> against the default configuration, both with <code>-std=c++20</code>, at <code>-O0</code> and <code>-O2</code>.</p> <p>The saving is small, and only <abbr title="GNU Compiler Collection">GCC</abbr> shows it: libstdc++'s <code>&lt;format&gt;</code> is an additional header that nothing else in the translation unit includes, so the macro removes it (and the headers it pulls in). With libc++ (Apple clang), other standard headers include <code>&lt;format&gt;</code> anyway, so the macro only removes the library's own formatter, and the difference is within the noise.</p> <p>The trade-off: the <code>std::formatter&lt;basic_json&gt;</code> specialization is removed, so <code class=highlight><span class=n>std</span><span class=o>::</span><span class=n>format</span><span class=p>(</span><span class=s>"{}"</span><span class=p>,</span><span class=w> </span><span class=n>j</span><span class=p>)</span></code>, and <code class=highlight><span class=n>std</span><span class=o>::</span><span class=n>format_to</span></code> with a <abbr title="JavaScript Object Notation">JSON</abbr> value no longer compile (in a test with both compilers on macOS, the error was that <code>std::formatter</code> must be specialized for the type). Use <a href=../../api/basic_json/dump/ ><code>dump()</code></a>, or the stream operators, instead.</p> <h2 id=switch-off-ranges-support>Switch off ranges support<a class=headerlink href=#switch-off-ranges-support title="Permanent link">&para;</a></h2> <p>With C++20 and a standard library that provides <code>&lt;ranges&gt;</code>, the library includes it to declare the <a href=../../api/basic_json/items/ ><code>items()</code></a> proxy a <em>borrowed range</em>, and uses the <code>std::ranges</code> concepts and algorithms for construction from range views and for iterator input (see <a href=../../api/macros/json_has_ranges/ ><code>JSON_HAS_RANGES</code></a>). If you do not need these, switch the detection off for the whole project:</p> <div class=highlight><pre><span></span><code><span class=nb>target_compile_definitions</span><span class=p>(</span><span class=s>my_target</span><span class=w> </span><span class=s>PRIVATE</span><span class=w> </span><span class=s>JSON_HAS_RANGES=0</span><span class=p>)</span>
</code></pre></div> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Ranges off (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1283 ms / 1544 ms</td> <td style="text-align: right;">1237 ms / 1495 ms</td> <td style="text-align: right;">−4% / −3%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">2026 ms / 2482 ms</td> <td style="text-align: right;">2004 ms / 2464 ms</td> <td style="text-align: right;">−1% / −1%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1350 ms / 2278 ms</td> <td style="text-align: right;">1311 ms / 2284 ms</td> <td style="text-align: right;">−3% / 0%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2715 ms / 4351 ms</td> <td style="text-align: right;">2705 ms / 4427 ms</td> <td style="text-align: right;">0% / +2%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with <code>JSON_HAS_RANGES=0</code> against the default configuration, both with <code>-std=c++20</code>, at <code>-O0</code> and <code>-O2</code>.</p> <p>The saving is small as well, and with <abbr title="GNU Compiler Collection">GCC</abbr> it is not distinguishable from the noise: its <code>&lt;format&gt;</code> includes <code>&lt;span&gt;</code>, so with <code>std::format</code> support left on, part of the ranges machinery is still parsed. Both macros together save more than either alone:</p> <div class=highlight><pre><span></span><code><span class=nb>target_compile_definitions</span><span class=p>(</span><span class=s>my_target</span><span class=w> </span><span class=s>PRIVATE</span><span class=w> </span><span class=s>JSON_HAS_STD_FORMAT=0</span><span class=w> </span><span class=s>JSON_HAS_RANGES=0</span><span class=p>)</span>
</code></pre></div> <table> <thead> <tr> <th>Compiler</th> <th>Translation unit</th> <th style="text-align: right;">Default (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Both off (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;">Change</th> </tr> </thead> <tbody> <tr> <td>Apple clang</td> <td>model</td> <td style="text-align: right;">1283 ms / 1544 ms</td> <td style="text-align: right;">1223 ms / 1504 ms</td> <td style="text-align: right;">−5% / −3%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>model</td> <td style="text-align: right;">2026 ms / 2482 ms</td> <td style="text-align: right;">1914 ms / 2378 ms</td> <td style="text-align: right;">−6% / −4%</td> </tr> <tr> <td>Apple clang</td> <td>parsing</td> <td style="text-align: right;">1350 ms / 2278 ms</td> <td style="text-align: right;">1311 ms / 2271 ms</td> <td style="text-align: right;">−3% / 0%</td> </tr> <tr> <td><abbr title="GNU Compiler Collection">GCC</abbr> 16</td> <td>parsing</td> <td style="text-align: right;">2715 ms / 4351 ms</td> <td style="text-align: right;">2635 ms / 4260 ms</td> <td style="text-align: right;">−3% / −2%</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time with <code>JSON_HAS_STD_FORMAT=0</code> and <code>JSON_HAS_RANGES=0</code> against the default configuration, both with <code>-std=c++20</code>, at <code>-O0</code> and <code>-O2</code>.</p> <p>The trade-offs of <code>JSON_HAS_RANGES=0</code> are larger than those of the other options on this page:</p> <ul> <li><code>items()</code> is no longer a borrowed range. On a temporary, <code class=highlight><span class=n>std</span><span class=o>::</span><span class=n>ranges</span><span class=o>::</span><span class=n>begin</span><span class=p>(</span><span class=n>make_json</span><span class=p>().</span><span class=n>items</span><span class=p>())</span></code> no longer compiles, and <code>std::ranges</code> algorithms such as <code class=highlight><span class=n>std</span><span class=o>::</span><span class=n>ranges</span><span class=o>::</span><span class=n>find_if</span><span class=p>(</span><span class=n>make_json</span><span class=p>().</span><span class=n>items</span><span class=p>(),</span><span class=w> </span><span class=n>pred</span><span class=p>)</span></code> return <code>std::ranges::dangling</code> instead of an iterator, so code that uses the result no longer compiles. Calling them on <code class=highlight><span class=n>j</span><span class=p>.</span><span class=n>items</span><span class=p>()</span></code> for a named <code>j</code> is not affected.</li> <li><a href=../../api/macros/json_has_range_view_conversion/ ><code>JSON_HAS_RANGE_VIEW_CONVERSION</code></a> becomes <code>0</code>, so a <abbr title="JavaScript Object Notation">JSON</abbr> array can no longer be constructed from a <code>std::ranges::view</code> such as the result of <code>std::views::filter</code>. The assignment <code class=highlight><span class=n>json</span><span class=w> </span><span class=n>j</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>|</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>views</span><span class=o>::</span><span class=n>filter</span><span class=p>(</span><span class=n>pred</span><span class=p>);</span></code> no longer compiles.</li> <li>Parsing from an iterator pair loses the C++20 fast path for contiguous iterators that are not pointers (for example those of <code>std::vector</code>) and falls back to byte-at-a-time scanning. The result is the same; parsing may be slower (not measured here).</li> </ul> <p>The first two were checked with both compilers on macOS; the third is read from the library's source.</p> <h2 id=use-c20-modules>Use C++20 modules<a class=headerlink href=#use-c20-modules title="Permanent link">&para;</a></h2> <p>With a toolchain that supports named modules, <code>import nlohmann.json;</code> compiles the library once into a module and avoids parsing the header in every translation unit. See <a href=../../features/modules/ >Modules</a> for requirements and known issues. Module support is experimental and currently depends heavily on the compiler version.</p> <div class=nj-fig-wrap> <p><svg class="nj-fig nj-charts nj-charts--compile" viewbox="0 0 440 282" role=img aria-labelledby="nj-charts-mod nj-charts-mod-d" xmlns=http://www.w3.org/2000/svg> <title id=nj-charts-mod>Compile time per translation unit with import nlohmann.json at -O0, and the one-off cost of the module</title> <desc id=nj-charts-mod-d>Horizontal bars, negative is faster, medians of nine runs, -std=c++20 for both. model TU, Apple clang: -48 % (1311 ms to 680 ms); model TU, G&#8203;CC 16: -47 % (2156 ms to 1153 ms); parsing TU, Apple clang: -42 % (1387 ms to 800 ms); parsing TU, G&#8203;CC 16: -36 % (2838 ms to 1810 ms); one-off build, Apple clang: 1630 ms; oLine truncated
clang++<span class=w> </span>-std<span class=o>=</span>c++20<span class=w> </span>-fcxx-modules<span class=w> </span>-O0<span class=w> </span>-I<span class=w> </span>single_include<span class=w> </span>-c<span class=w> </span>-x<span class=w> </span>c++-module<span class=w> </span>src/modules/json.cppm<span class=w> </span><span class=se>\</span>
<span class=w> </span>-fmodule-output<span class=o>=</span>nlohmann.json.pcm<span class=w> </span>-o<span class=w> </span>json_mod.o
clang++<span class=w> </span>-std<span class=o>=</span>c++20<span class=w> </span>-fcxx-modules<span class=w> </span>-O0<span class=w> </span>-fmodule-file<span class=o>=</span>nlohmann.json<span class=o>=</span>nlohmann.json.pcm<span class=w> </span>-c<span class=w> </span>model.cpp
@@ -70,4 +73,4 @@ clang++<span class=w> </span>-std<span class=o>=</span>c++17<span class=w> </spa
<span class=c1># GCC 16 (Homebrew on macOS): pch.hpp.gch next to pch.hpp is picked up by -include pch.hpp</span>
g++-16<span class=w> </span>--sysroot<span class=o>=</span><span class=k>$(</span>xcrun<span class=w> </span>--show-sdk-path<span class=k>)</span><span class=w> </span>-std<span class=o>=</span>c++17<span class=w> </span>-O0<span class=w> </span>-I<span class=w> </span>single_include<span class=w> </span>-x<span class=w> </span>c++-header<span class=w> </span>pch.hpp<span class=w> </span>-o<span class=w> </span>pch.hpp.gch
g++-16<span class=w> </span>--sysroot<span class=o>=</span><span class=k>$(</span>xcrun<span class=w> </span>--show-sdk-path<span class=k>)</span><span class=w> </span>-std<span class=o>=</span>c++17<span class=w> </span>-O0<span class=w> </span>-I<span class=w> </span>single_include<span class=w> </span>-include<span class=w> </span>pch.hpp<span class=w> </span>-Winvalid-pch<span class=w> </span>-c<span class=w> </span>model.cpp
</code></pre></div> </details> <h2 id=options-without-effect-on-compile-times>Options without effect on compile times<a class=headerlink href=#options-without-effect-on-compile-times title="Permanent link">&para;</a></h2> <p>Some configuration macros change what the library declares, but do not measurably change compile times:</p> <table> <thead> <tr> <th>Macro</th> <th style="text-align: right;">Apple clang, model (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;"><abbr title="GNU Compiler Collection">GCC</abbr> 16, model (<code>-O0</code> / <code>-O2</code>)</th> </tr> </thead> <tbody> <tr> <td>default</td> <td style="text-align: right;">1051 ms / 1300 ms</td> <td style="text-align: right;">1801 ms / 2106 ms</td> </tr> <tr> <td><a href=../../api/macros/json_no_io/ ><code>JSON_NO_IO</code></a></td> <td style="text-align: right;">1034 ms / 1288 ms</td> <td style="text-align: right;">1756 ms / 2087 ms</td> </tr> <tr> <td><a href=../../api/macros/json_use_global_udls/ ><code>JSON_USE_GLOBAL_UDLS</code></a><code>=0</code></td> <td style="text-align: right;">1055 ms / 1298 ms</td> <td style="text-align: right;">1783 ms / 2109 ms</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time of the model translation unit with each macro defined; the first row is the default configuration for comparison.</p> <p><code>JSON_NO_IO</code> removes the library's stream functions and its <code>#include</code>s of <code>&lt;istream&gt;</code> and <code>&lt;ostream&gt;</code>, but with the default C++17 settings <code>&lt;filesystem&gt;</code> includes these headers anyway (and with libc++, <code>&lt;vector&gt;</code> already includes <code>&lt;streambuf&gt;</code> via <code>&lt;locale&gt;</code>), so only a few hundred lines of the library's own stream code go away. It also does not change what the translation unit instantiates. On the parsing translation unit, the change is 0% / 0% (Apple clang) and −2% / 0% (<abbr title="GNU Compiler Collection">GCC</abbr>). To get a saving, combine it with <a href=#switch-off-filesystem-support>switching off filesystem support</a>.</p> <p><code>JSON_USE_GLOBAL_UDLS</code> only controls <em>where</em> the literals are declared; to avoid their cost, use <code>JSON_NO_AUTOMATIC_UDLS</code> instead.</p> <h2 id=see-also>See also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><a href=../../api/macros/json_has_filesystem/ ><code>JSON_HAS_FILESYSTEM</code></a> - control the conversions from and to <code>std::filesystem::path</code></li> <li><a href=../../api/macros/json_no_automatic_udls/ ><code>JSON_NO_AUTOMATIC_UDLS</code></a> - do not include the user-defined string literals automatically</li> <li><a href=../../features/modules/ >Modules</a> - C++20 module support</li> <li><a href=../ >Header only</a> - including the library</li> <li><a href=../../api/macros/ >Macros</a> - reference of all macros</li> <li><a href=../../features/macros/ >Supported Macros</a> - overview of all configuration macros</li> <li><a href=../../features/performance/ >Performance</a> - run-time performance</li> <li><a href=../../api/macros/json_no_io/ ><code>JSON_NO_IO</code></a> - remove all stream and file I/O</li> </ul> <!-- https://squidfunk.github.io/mkdocs-material/reference/tooltips/#adding-a-glossary --> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date" title="October 27, 2026 06:41:42 UTC">October 27, 2026</span> </span> </aside> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../pkg-config/ class="md-footer__link md-footer__link--prev" aria-label="Previous: Pkg-config"> <div class="md-footer__button md-icon"> <svLine truncated
</code></pre></div> </details> <h2 id=options-without-effect-on-compile-times>Options without effect on compile times<a class=headerlink href=#options-without-effect-on-compile-times title="Permanent link">&para;</a></h2> <p>Some configuration macros change what the library declares, but do not measurably change compile times:</p> <table> <thead> <tr> <th>Macro</th> <th style="text-align: right;">Apple clang, model (<code>-O0</code> / <code>-O2</code>)</th> <th style="text-align: right;"><abbr title="GNU Compiler Collection">GCC</abbr> 16, model (<code>-O0</code> / <code>-O2</code>)</th> </tr> </thead> <tbody> <tr> <td>default</td> <td style="text-align: right;">1051 ms / 1300 ms</td> <td style="text-align: right;">1801 ms / 2106 ms</td> </tr> <tr> <td><a href=../../api/macros/json_no_io/ ><code>JSON_NO_IO</code></a></td> <td style="text-align: right;">1034 ms / 1288 ms</td> <td style="text-align: right;">1756 ms / 2087 ms</td> </tr> <tr> <td><a href=../../api/macros/json_use_global_udls/ ><code>JSON_USE_GLOBAL_UDLS</code></a><code>=0</code></td> <td style="text-align: right;">1055 ms / 1298 ms</td> <td style="text-align: right;">1783 ms / 2109 ms</td> </tr> </tbody> </table> <p class=nj-table-caption>Compile time of the model translation unit with each macro defined; the first row is the default configuration for comparison.</p> <p><code>JSON_NO_IO</code> removes the library's stream functions and its <code>#include</code>s of <code>&lt;istream&gt;</code> and <code>&lt;ostream&gt;</code>, but with the default C++17 settings <code>&lt;filesystem&gt;</code> includes these headers anyway (and with libc++, <code>&lt;vector&gt;</code> already includes <code>&lt;streambuf&gt;</code> via <code>&lt;locale&gt;</code>), so only a few hundred lines of the library's own stream code go away. It also does not change what the translation unit instantiates. On the parsing translation unit, the change is 0% / 0% (Apple clang) and −2% / 0% (<abbr title="GNU Compiler Collection">GCC</abbr>). To get a saving, combine it with <a href=#switch-off-filesystem-support>switching off filesystem support</a>.</p> <p><code>JSON_USE_GLOBAL_UDLS</code> only controls <em>where</em> the literals are declared; to avoid their cost, use <code>JSON_NO_AUTOMATIC_UDLS</code> instead.</p> <h2 id=see-also>See also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><a href=../../api/macros/json_has_filesystem/ ><code>JSON_HAS_FILESYSTEM</code></a> - control the conversions from and to <code>std::filesystem::path</code></li> <li><a href=../../api/macros/json_has_std_format/ ><code>JSON_HAS_STD_FORMAT</code></a> - control the <code>std::formatter</code> specialization</li> <li><a href=../../api/macros/json_has_ranges/ ><code>JSON_HAS_RANGES</code></a> - control the use of <code>std::ranges</code></li> <li><a href=../../api/macros/json_no_automatic_udls/ ><code>JSON_NO_AUTOMATIC_UDLS</code></a> - do not include the user-defined string literals automatically</li> <li><a href=../../features/modules/ >Modules</a> - C++20 module support</li> <li><a href=../ >Header only</a> - including the library</li> <li><a href=../../api/macros/ >Macros</a> - reference of all macros</li> <li><a href=../../features/macros/ >Supported Macros</a> - overview of all configuration macros</li> <li><a href=../../features/performance/ >Performance</a> - run-time performance</li> <li><a href=../../api/macros/json_no_io/ ><code>JSON_NO_IO</code></a> - remove all stream and file I/O</li> </ul> <!-- https://squidfunk.github.io/mkdocs-material/reference/tooltips/#adding-a-glossary --> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date" title="November 5, 2026 15:04:39 UTC">November 5, 2026</span> </span> </aside> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.4Line truncated
+66 -1
View File
@@ -6,6 +6,8 @@ Measurements
The numbers below are medians of the wall-clock time of nine runs compiling a single translation unit with `-std=c++17 -c` against the single-header version, with Apple clang 21.0.0 (clang-2100.3.34.2) and Homebrew GCC 16.2.0 on macOS (Apple M1 Max). All configurations were run interleaved, in alternating order. They show the order of magnitude to expect; measure your own code before and after a change.
The two sections on `std::format` and ranges apply to C++20 only and were measured with `-std=c++20`, so their baselines are slower than the others. Their differences are mostly within the run-to-run noise of a few percent: two complete runs of the same configuration differed by up to 10% in the median. The tables show the later run (one outlier cell was repeated).
The translation units are listed below. They replace the ones used for earlier versions of this page, whose sources were not published, so the numbers differ from earlier versions.
Measured translation units
@@ -61,7 +63,7 @@ void to_json(nlohmann::json& j, const person& p);
void from_json(const nlohmann::json& j, person& p);
```
Change in compile time at `-O0` against the default configuration of the same translation unit, taken from the tables below (medians of nine runs, see above). * computed from the milliseconds in [Options without effect on compile times](#options-without-effect-on-compile-times).
Change in compile time at `-O0` against the default configuration of the same translation unit, taken from the tables below (medians of nine runs, see above; the `std::format` and ranges rows are measured with `-std=c++20`). * computed from the milliseconds in [Options without effect on compile times](#options-without-effect-on-compile-times).
## Include `json_fwd.hpp` in headers
@@ -192,6 +194,67 @@ Compile time with filesystem support switched off and `JSON_NO_IO` defined, agai
The trade-off: the library's own `to_json`/`from_json` overloads for `std::filesystem::path` (which store the path as UTF-8) are removed. In a test with both compilers on macOS, paths still converted through their implicit conversion from and to `std::string`; whether that fallback exists depends on the platform's native path string type (`std::wstring` on Windows), so check code that converts paths. `JSON_NO_IO` additionally removes all stream functions (see [Options without effect](#options-without-effect-on-compile-times)).
## Switch off `std::format` support
With C++20 and a standard library that provides `<format>`, the library includes it to provide a [`std::formatter<basic_json>`](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) specialization (see [`JSON_HAS_STD_FORMAT`](https://json.nlohmann.me/api/macros/json_has_std_format/index.md)). If you do not format JSON values with `std::format`, switch the detection off for the whole project:
```
target_compile_definitions(my_target PRIVATE JSON_HAS_STD_FORMAT=0)
```
| Compiler | Translation unit | Default (`-O0` / `-O2`) | `std::format` off (`-O0` / `-O2`) | Change |
| ----------- | ---------------- | ----------------------- | --------------------------------- | --------- |
| Apple clang | model | 1283 ms / 1544 ms | 1269 ms / 1539 ms | −1% / 0% |
| GCC 16 | model | 2026 ms / 2482 ms | 1944 ms / 2416 ms | −4% / −3% |
| Apple clang | parsing | 1350 ms / 2278 ms | 1347 ms / 2300 ms | 0% / +1% |
| GCC 16 | parsing | 2715 ms / 4351 ms | 2644 ms / 4287 ms | −3% / −1% |
Compile time with `JSON_HAS_STD_FORMAT=0` against the default configuration, both with `-std=c++20`, at `-O0` and `-O2`.
The saving is small, and only GCC shows it: libstdc++'s `<format>` is an additional header that nothing else in the translation unit includes, so the macro removes it (and the headers it pulls in). With libc++ (Apple clang), other standard headers include `<format>` anyway, so the macro only removes the library's own formatter, and the difference is within the noise.
The trade-off: the `std::formatter<basic_json>` specialization is removed, so `std::format("{}", j)`, and `std::format_to` with a JSON value no longer compile (in a test with both compilers on macOS, the error was that `std::formatter` must be specialized for the type). Use [`dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md), or the stream operators, instead.
## Switch off ranges support
With C++20 and a standard library that provides `<ranges>`, the library includes it to declare the [`items()`](https://json.nlohmann.me/api/basic_json/items/index.md) proxy a *borrowed range*, and uses the `std::ranges` concepts and algorithms for construction from range views and for iterator input (see [`JSON_HAS_RANGES`](https://json.nlohmann.me/api/macros/json_has_ranges/index.md)). If you do not need these, switch the detection off for the whole project:
```
target_compile_definitions(my_target PRIVATE JSON_HAS_RANGES=0)
```
| Compiler | Translation unit | Default (`-O0` / `-O2`) | Ranges off (`-O0` / `-O2`) | Change |
| ----------- | ---------------- | ----------------------- | -------------------------- | --------- |
| Apple clang | model | 1283 ms / 1544 ms | 1237 ms / 1495 ms | −4% / −3% |
| GCC 16 | model | 2026 ms / 2482 ms | 2004 ms / 2464 ms | −1% / −1% |
| Apple clang | parsing | 1350 ms / 2278 ms | 1311 ms / 2284 ms | −3% / 0% |
| GCC 16 | parsing | 2715 ms / 4351 ms | 2705 ms / 4427 ms | 0% / +2% |
Compile time with `JSON_HAS_RANGES=0` against the default configuration, both with `-std=c++20`, at `-O0` and `-O2`.
The saving is small as well, and with GCC it is not distinguishable from the noise: its `<format>` includes `<span>`, so with `std::format` support left on, part of the ranges machinery is still parsed. Both macros together save more than either alone:
```
target_compile_definitions(my_target PRIVATE JSON_HAS_STD_FORMAT=0 JSON_HAS_RANGES=0)
```
| Compiler | Translation unit | Default (`-O0` / `-O2`) | Both off (`-O0` / `-O2`) | Change |
| ----------- | ---------------- | ----------------------- | ------------------------ | --------- |
| Apple clang | model | 1283 ms / 1544 ms | 1223 ms / 1504 ms | −5% / −3% |
| GCC 16 | model | 2026 ms / 2482 ms | 1914 ms / 2378 ms | −6% / −4% |
| Apple clang | parsing | 1350 ms / 2278 ms | 1311 ms / 2271 ms | −3% / 0% |
| GCC 16 | parsing | 2715 ms / 4351 ms | 2635 ms / 4260 ms | −3% / −2% |
Compile time with `JSON_HAS_STD_FORMAT=0` and `JSON_HAS_RANGES=0` against the default configuration, both with `-std=c++20`, at `-O0` and `-O2`.
The trade-offs of `JSON_HAS_RANGES=0` are larger than those of the other options on this page:
- `items()` is no longer a borrowed range. On a temporary, `std::ranges::begin(make_json().items())` no longer compiles, and `std::ranges` algorithms such as `std::ranges::find_if(make_json().items(), pred)` return `std::ranges::dangling` instead of an iterator, so code that uses the result no longer compiles. Calling them on `j.items()` for a named `j` is not affected.
- [`JSON_HAS_RANGE_VIEW_CONVERSION`](https://json.nlohmann.me/api/macros/json_has_range_view_conversion/index.md) becomes `0`, so a JSON array can no longer be constructed from a `std::ranges::view` such as the result of `std::views::filter`. The assignment `json j = v | std::views::filter(pred);` no longer compiles.
- Parsing from an iterator pair loses the C++20 fast path for contiguous iterators that are not pointers (for example those of `std::vector`) and falls back to byte-at-a-time scanning. The result is the same; parsing may be slower (not measured here).
The first two were checked with both compilers on macOS; the third is read from the library's source.
## Use C++20 modules
With a toolchain that supports named modules, `import nlohmann.json;` compiles the library once into a module and avoids parsing the header in every translation unit. See [Modules](https://json.nlohmann.me/features/modules/index.md) for requirements and known issues. Module support is experimental and currently depends heavily on the compiler version.
@@ -290,6 +353,8 @@ Compile time of the model translation unit with each macro defined; the first ro
## See also
- [`JSON_HAS_FILESYSTEM`](https://json.nlohmann.me/api/macros/json_has_filesystem/index.md) - control the conversions from and to `std::filesystem::path`
- [`JSON_HAS_STD_FORMAT`](https://json.nlohmann.me/api/macros/json_has_std_format/index.md) - control the `std::formatter` specialization
- [`JSON_HAS_RANGES`](https://json.nlohmann.me/api/macros/json_has_ranges/index.md) - control the use of `std::ranges`
- [`JSON_NO_AUTOMATIC_UDLS`](https://json.nlohmann.me/api/macros/json_no_automatic_udls/index.md) - do not include the user-defined string literals automatically
- [Modules](https://json.nlohmann.me/features/modules/index.md) - C++20 module support
- [Header only](https://json.nlohmann.me/integration/index.md) - including the library
+1 -1
View File
@@ -1 +1 @@
{"config":{"lang":["en"],"separator":"[\\s\\-\\.]","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"JSON for Modern C++","text":"<ul> <li> <p> Features</p> <p>Creating, parsing, accessing, and serializing JSON values, converting your own C++ types, JSON Pointer/Patch/Merge Patch, binary formats, zero-copy views, and more.</p> <p> Features</p> </li> <li> <p> Integration</p> <p>Add the library to your project via a single header, CMake, a package manager, or pkg-config.</p> <p> Integration</p> </li> <li> <p> API documentation</p> <p>The complete reference for <code>basic_json</code> and its member functions, types, and related classes, as well as for <code>json_document</code> and <code>json_view</code>.</p> <p> API documentation</p> </li> <li> <p> FAQ</p> <p>Answers to common questions and known surprises when using the library.</p> <p> FAQ</p> </li> <li> <p> Releases</p> <p>What changed in each release, with links to the relevant documentation.</p> <p> Releases</p> </li> <li> <p> Community</p> <p>The ecosystem, contribution guidelines, governance, and quality assurance around the project.</p> <p> Community</p> </li> </ul> <p> </p>"},{"location":"api/is_json_view/","title":"nlohmann::is_json_view","text":"<p>Defined in header <code>&lt;nlohmann/json_view.hpp&gt;</code></p> <pre><code>template&lt;typename T&gt;\nstruct is_json_view;\n</code></pre> <p>A type trait: <code>is_json_view&lt;T&gt;::value</code> is <code>true</code> if <code>T</code> is a <code>basic_json_view</code> of any <code>BasicJsonType</code> and any <code>view_mode</code> -- <code>json_view</code>, <code>json_editable_view</code>, <code>ordered_json_view</code>, ... -- and <code>false</code> otherwise, for <code>basic_json</code> as well.</p> <p>It is meant for constraining templates that accept views, in particular a <code>from_json()</code> that should read views directly: <code>get&lt;T&gt;()</code> on a view calls a <code>from_json()</code> with the view only if that <code>from_json()</code> accepts views but not arbitrary types.</p>"},{"location":"api/is_json_view/#template-parameters","title":"Template parameters","text":"<code>T</code> the type to check (without cv-qualifiers or references)"},{"location":"api/is_json_view/#notes","title":"Notes","text":"<p>A view is recognized by its member type <code>basic_json_type</code> (a <code>basic_json</code> specialization) and its <code>materialize()</code> returning that type, so the trait needs no declaration of the view class.</p>"},{"location":"api/is_json_view/#examples","title":"Examples","text":"Example <p>The example below shows the trait, and a <code>from_json()</code> constrained to <code>json</code> values and views: <code>get&lt;T&gt;()</code> on a view reads the view directly.</p> <pre><code>#include &lt;iostream&gt;\n#include &lt;type_traits&gt;\n#include &lt;nlohmann/json_view.hpp&gt;\n\nusing nlohmann::json;\n\nnamespace ns\n{\nstruct person\n{\n std::string name;\n int age = 0;\n};\n\n// reads json values and views (of any document type), but nothing else\ntemplate &lt; typename J, typename std::enable_if &lt; nlohmann::is_json_view&lt;J&gt;::value || std::is_same&lt;J, json&gt;::value, int &gt;::type = 0 &gt;\nvoid from_json(const J&amp; j, person&amp; p)\n{\n p.name = j.at(\"name\").template get&lt;std::string&gt;();\n p.age = j.at(\"age\").template get&lt;int&gt;();\n}\n} // namespace ns\n\nint main()\n{\n std::cout &lt;&lt; std::boolalpha\n &lt;&lt; nlohmann::is_json_view&lt;nlohmann::json_view&gt;::value &lt;&lt; ' '\n &lt;&lt; nlohmann::is_json_view&lt;nlohmann::ordered_json_editable_view&gt;::value &lt;&lt; ' '\n &lt;&lt; nlohmann::is_json_view&lt;json&gt;::value &lt;&lt; '\\n';\n\n const nlohmann::json_document doc = nlohmann::json_document::parse(R\"({\"name\": \"Ada\", \"age\": 36})\");\n const auto p = doc.root().get&lt;ns::person&gt;(); // reads the view, no json value is built\n std::cout &lt;&lt; p.name &lt;&lt; ' ' &lt;&lt; p.age &lt;&lt; '\\n';\n}\n</code></pre> <p>Output:</p> <pre><code>true true false\nAda 36\n</code></pre>"},{"location":"api/is_json_view/#see-also","title":"See also","text":"<ul> <li>basic_json_view - a handle to one value of a document</li> <li>get - which conversions read the view directly</li> <li>view_mode - read-only or editable</li> <li>Writing generic code - functions and <code>from_json()</code> for views</li> </ul>"},{"location":"api/is_json_view/#version-history","title":"Version history","text":"<p>Added in version 3.13.0 unreleased.</p>"},{"location":"api/json/","title":"nlohmann::json","text":"<pre><code>using json = basic_json&lt;&gt;;\n</code></pre> <p>This type is the default specialization of the basic_json class which uses the standard template types.</p>"},{"location":"api/json/#examples","title":"Examples","text":"Example <p>The example below demonstrates how Line truncated
{"config":{"lang":["en"],"separator":"[\\s\\-\\.]","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"JSON for Modern C++","text":"<ul> <li> <p> Features</p> <p>Creating, parsing, accessing, and serializing JSON values, converting your own C++ types, JSON Pointer/Patch/Merge Patch, binary formats, zero-copy views, and more.</p> <p> Features</p> </li> <li> <p> Integration</p> <p>Add the library to your project via a single header, CMake, a package manager, or pkg-config.</p> <p> Integration</p> </li> <li> <p> API documentation</p> <p>The complete reference for <code>basic_json</code> and its member functions, types, and related classes, as well as for <code>json_document</code> and <code>json_view</code>.</p> <p> API documentation</p> </li> <li> <p> FAQ</p> <p>Answers to common questions and known surprises when using the library.</p> <p> FAQ</p> </li> <li> <p> Releases</p> <p>What changed in each release, with links to the relevant documentation.</p> <p> Releases</p> </li> <li> <p> Community</p> <p>The ecosystem, contribution guidelines, governance, and quality assurance around the project.</p> <p> Community</p> </li> </ul> <p> </p>"},{"location":"api/is_json_view/","title":"nlohmann::is_json_view","text":"<p>Defined in header <code>&lt;nlohmann/json_view.hpp&gt;</code></p> <pre><code>template&lt;typename T&gt;\nstruct is_json_view;\n</code></pre> <p>A type trait: <code>is_json_view&lt;T&gt;::value</code> is <code>true</code> if <code>T</code> is a <code>basic_json_view</code> of any <code>BasicJsonType</code> and any <code>view_mode</code> -- <code>json_view</code>, <code>json_editable_view</code>, <code>ordered_json_view</code>, ... -- and <code>false</code> otherwise, for <code>basic_json</code> as well.</p> <p>It is meant for constraining templates that accept views, in particular a <code>from_json()</code> that should read views directly: <code>get&lt;T&gt;()</code> on a view calls a <code>from_json()</code> with the view only if that <code>from_json()</code> accepts views but not arbitrary types.</p>"},{"location":"api/is_json_view/#template-parameters","title":"Template parameters","text":"<code>T</code> the type to check (without cv-qualifiers or references)"},{"location":"api/is_json_view/#notes","title":"Notes","text":"<p>A view is recognized by its member type <code>basic_json_type</code> (a <code>basic_json</code> specialization) and its <code>materialize()</code> returning that type, so the trait needs no declaration of the view class.</p>"},{"location":"api/is_json_view/#examples","title":"Examples","text":"Example <p>The example below shows the trait, and a <code>from_json()</code> constrained to <code>json</code> values and views: <code>get&lt;T&gt;()</code> on a view reads the view directly.</p> <pre><code>#include &lt;iostream&gt;\n#include &lt;type_traits&gt;\n#include &lt;nlohmann/json_view.hpp&gt;\n\nusing nlohmann::json;\n\nnamespace ns\n{\nstruct person\n{\n std::string name;\n int age = 0;\n};\n\n// reads json values and views (of any document type), but nothing else\ntemplate &lt; typename J, typename std::enable_if &lt; nlohmann::is_json_view&lt;J&gt;::value || std::is_same&lt;J, json&gt;::value, int &gt;::type = 0 &gt;\nvoid from_json(const J&amp; j, person&amp; p)\n{\n p.name = j.at(\"name\").template get&lt;std::string&gt;();\n p.age = j.at(\"age\").template get&lt;int&gt;();\n}\n} // namespace ns\n\nint main()\n{\n std::cout &lt;&lt; std::boolalpha\n &lt;&lt; nlohmann::is_json_view&lt;nlohmann::json_view&gt;::value &lt;&lt; ' '\n &lt;&lt; nlohmann::is_json_view&lt;nlohmann::ordered_json_editable_view&gt;::value &lt;&lt; ' '\n &lt;&lt; nlohmann::is_json_view&lt;json&gt;::value &lt;&lt; '\\n';\n\n const nlohmann::json_document doc = nlohmann::json_document::parse(R\"({\"name\": \"Ada\", \"age\": 36})\");\n const auto p = doc.root().get&lt;ns::person&gt;(); // reads the view, no json value is built\n std::cout &lt;&lt; p.name &lt;&lt; ' ' &lt;&lt; p.age &lt;&lt; '\\n';\n}\n</code></pre> <p>Output:</p> <pre><code>true true false\nAda 36\n</code></pre>"},{"location":"api/is_json_view/#see-also","title":"See also","text":"<ul> <li>basic_json_view - a handle to one value of a document</li> <li>get - which conversions read the view directly</li> <li>view_mode - read-only or editable</li> <li>Writing generic code - functions and <code>from_json()</code> for views</li> </ul>"},{"location":"api/is_json_view/#version-history","title":"Version history","text":"<p>Added in version 3.13.0 unreleased.</p>"},{"location":"api/json/","title":"nlohmann::json","text":"<pre><code>using json = basic_json&lt;&gt;;\n</code></pre> <p>This type is the default specialization of the basic_json class which uses the standard template types.</p>"},{"location":"api/json/#examples","title":"Examples","text":"Example <p>The example below demonstrates how Line truncated
+404 -404
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.