Commit 84939c1
Add a contiguous fast path for scanning numbers
scan_number() reads a number one character at a time through the input
adapter (get()) and appends each byte to token_buffer (add()) before
converting. For contiguous input, the per-character get()/add() overhead
dominates: it is roughly two thirds of the time spent on number-heavy
parsing, far more than the value conversion itself.
Add scan_number_bulk_contiguous(), which parses the whole number token
straight from the input buffer: it validates and classifies the extent
with the same grammar as scan_number()'s state machine, materializes
token_buffer in one copy (substituting the locale decimal point exactly as
scan_number() does), advances the adapter, and reuses the shared
convert_number() tail. On anything it does not recognize as a well-formed
number it makes no state change and returns token_type::uninitialized, so
the caller falls back to scan_number(), which then produces the exact
diagnostic. Errors and their positions are therefore unchanged.
The conversion tail is factored out of scan_number() into convert_number()
so both scanners share it; the fast path is selected by tag dispatch on the
existing bulk_scan capability, so streaming/wide/user adapters are
unaffected.
Measured on pointer input, g++ 13 -O3:
- integers: parse +65%, accept +98%
- floats: parse +39%, accept +70%
Verified: 2,000,000 randomized number documents (including overflow-range
integers, long digit strings and %.17g doubles) parse identically via the
contiguous path and the streaming byte path, matching value, type and
round-trip text; the locale suite and existing parser/lexer/conversions/
deserialization tests pass; a new "lexer number fast path" test checks
contiguous-vs-streaming parity, token classification, and that malformed
numbers are rejected identically. Pure C++11, no intrinsics.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AXcDtEma2PjxgmPS9cQGzA
Signed-off-by: Niels Lohmann <mail@nlohmann.me>1 parent 190f4b6 commit 84939c1
3 files changed
Lines changed: 350 additions & 6 deletions
File tree
- include/nlohmann/detail/input
- single_include/nlohmann
- tests/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1769 | 1769 | | |
1770 | 1770 | | |
1771 | 1771 | | |
| 1772 | + | |
| 1773 | + | |
| 1774 | + | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
| 1781 | + | |
| 1782 | + | |
| 1783 | + | |
| 1784 | + | |
| 1785 | + | |
1772 | 1786 | | |
1773 | 1787 | | |
1774 | 1788 | | |
1775 | 1789 | | |
1776 | | - | |
1777 | | - | |
| 1790 | + | |
| 1791 | + | |
1778 | 1792 | | |
1779 | 1793 | | |
1780 | 1794 | | |
| |||
1807 | 1821 | | |
1808 | 1822 | | |
1809 | 1823 | | |
| 1824 | + | |
| 1825 | + | |
| 1826 | + | |
| 1827 | + | |
| 1828 | + | |
| 1829 | + | |
| 1830 | + | |
| 1831 | + | |
| 1832 | + | |
| 1833 | + | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + | |
| 1837 | + | |
| 1838 | + | |
| 1839 | + | |
| 1840 | + | |
| 1841 | + | |
| 1842 | + | |
| 1843 | + | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
| 1863 | + | |
| 1864 | + | |
| 1865 | + | |
| 1866 | + | |
| 1867 | + | |
| 1868 | + | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
| 1872 | + | |
| 1873 | + | |
| 1874 | + | |
| 1875 | + | |
| 1876 | + | |
| 1877 | + | |
| 1878 | + | |
| 1879 | + | |
| 1880 | + | |
| 1881 | + | |
| 1882 | + | |
| 1883 | + | |
| 1884 | + | |
| 1885 | + | |
| 1886 | + | |
| 1887 | + | |
| 1888 | + | |
| 1889 | + | |
| 1890 | + | |
| 1891 | + | |
| 1892 | + | |
| 1893 | + | |
| 1894 | + | |
| 1895 | + | |
| 1896 | + | |
| 1897 | + | |
| 1898 | + | |
| 1899 | + | |
| 1900 | + | |
| 1901 | + | |
| 1902 | + | |
| 1903 | + | |
| 1904 | + | |
| 1905 | + | |
| 1906 | + | |
| 1907 | + | |
| 1908 | + | |
| 1909 | + | |
| 1910 | + | |
| 1911 | + | |
| 1912 | + | |
| 1913 | + | |
| 1914 | + | |
| 1915 | + | |
| 1916 | + | |
| 1917 | + | |
| 1918 | + | |
| 1919 | + | |
| 1920 | + | |
| 1921 | + | |
| 1922 | + | |
| 1923 | + | |
| 1924 | + | |
| 1925 | + | |
| 1926 | + | |
| 1927 | + | |
| 1928 | + | |
| 1929 | + | |
| 1930 | + | |
| 1931 | + | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
| 1941 | + | |
| 1942 | + | |
| 1943 | + | |
| 1944 | + | |
| 1945 | + | |
1810 | 1946 | | |
1811 | 1947 | | |
1812 | 1948 | | |
| |||
2161 | 2297 | | |
2162 | 2298 | | |
2163 | 2299 | | |
2164 | | - | |
| 2300 | + | |
2165 | 2301 | | |
2166 | 2302 | | |
2167 | 2303 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9532 | 9532 | | |
9533 | 9533 | | |
9534 | 9534 | | |
| 9535 | + | |
| 9536 | + | |
| 9537 | + | |
| 9538 | + | |
| 9539 | + | |
| 9540 | + | |
| 9541 | + | |
| 9542 | + | |
| 9543 | + | |
| 9544 | + | |
| 9545 | + | |
| 9546 | + | |
| 9547 | + | |
| 9548 | + | |
9535 | 9549 | | |
9536 | 9550 | | |
9537 | 9551 | | |
9538 | 9552 | | |
9539 | | - | |
9540 | | - | |
| 9553 | + | |
| 9554 | + | |
9541 | 9555 | | |
9542 | 9556 | | |
9543 | 9557 | | |
| |||
9570 | 9584 | | |
9571 | 9585 | | |
9572 | 9586 | | |
| 9587 | + | |
| 9588 | + | |
| 9589 | + | |
| 9590 | + | |
| 9591 | + | |
| 9592 | + | |
| 9593 | + | |
| 9594 | + | |
| 9595 | + | |
| 9596 | + | |
| 9597 | + | |
| 9598 | + | |
| 9599 | + | |
| 9600 | + | |
| 9601 | + | |
| 9602 | + | |
| 9603 | + | |
| 9604 | + | |
| 9605 | + | |
| 9606 | + | |
| 9607 | + | |
| 9608 | + | |
| 9609 | + | |
| 9610 | + | |
| 9611 | + | |
| 9612 | + | |
| 9613 | + | |
| 9614 | + | |
| 9615 | + | |
| 9616 | + | |
| 9617 | + | |
| 9618 | + | |
| 9619 | + | |
| 9620 | + | |
| 9621 | + | |
| 9622 | + | |
| 9623 | + | |
| 9624 | + | |
| 9625 | + | |
| 9626 | + | |
| 9627 | + | |
| 9628 | + | |
| 9629 | + | |
| 9630 | + | |
| 9631 | + | |
| 9632 | + | |
| 9633 | + | |
| 9634 | + | |
| 9635 | + | |
| 9636 | + | |
| 9637 | + | |
| 9638 | + | |
| 9639 | + | |
| 9640 | + | |
| 9641 | + | |
| 9642 | + | |
| 9643 | + | |
| 9644 | + | |
| 9645 | + | |
| 9646 | + | |
| 9647 | + | |
| 9648 | + | |
| 9649 | + | |
| 9650 | + | |
| 9651 | + | |
| 9652 | + | |
| 9653 | + | |
| 9654 | + | |
| 9655 | + | |
| 9656 | + | |
| 9657 | + | |
| 9658 | + | |
| 9659 | + | |
| 9660 | + | |
| 9661 | + | |
| 9662 | + | |
| 9663 | + | |
| 9664 | + | |
| 9665 | + | |
| 9666 | + | |
| 9667 | + | |
| 9668 | + | |
| 9669 | + | |
| 9670 | + | |
| 9671 | + | |
| 9672 | + | |
| 9673 | + | |
| 9674 | + | |
| 9675 | + | |
| 9676 | + | |
| 9677 | + | |
| 9678 | + | |
| 9679 | + | |
| 9680 | + | |
| 9681 | + | |
| 9682 | + | |
| 9683 | + | |
| 9684 | + | |
| 9685 | + | |
| 9686 | + | |
| 9687 | + | |
| 9688 | + | |
| 9689 | + | |
| 9690 | + | |
| 9691 | + | |
| 9692 | + | |
| 9693 | + | |
| 9694 | + | |
| 9695 | + | |
| 9696 | + | |
| 9697 | + | |
| 9698 | + | |
| 9699 | + | |
| 9700 | + | |
| 9701 | + | |
| 9702 | + | |
| 9703 | + | |
| 9704 | + | |
| 9705 | + | |
| 9706 | + | |
| 9707 | + | |
| 9708 | + | |
9573 | 9709 | | |
9574 | 9710 | | |
9575 | 9711 | | |
| |||
9924 | 10060 | | |
9925 | 10061 | | |
9926 | 10062 | | |
9927 | | - | |
| 10063 | + | |
9928 | 10064 | | |
9929 | 10065 | | |
9930 | 10066 | | |
| |||
0 commit comments