← Commit list

0480ce1532

Daniel Stenberg
Daniel Stenberg
2026-09-18
SUCCESS Duration: 430s

Subject

perf-numparser: add number parsing performance test

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

tests/perf/Makefile.inc+1 -0
@@ -47,6 +47,7 @@ TESTS_C = \
base64enc.c \
dateparser.c \
maprintf.c \
+ numparser.c \
simpleformat.c \
snprintf.c \
urldecode.c \
tests/perf/README.md+8 -0
@@ -46,6 +46,14 @@ test does not:
./perf maprintf [loops]
+## `numparser`
+
+This test repeatedly converts over a hundred different numbers from a string
+to binary. Decimal, hexadecimal and octal numbers, each with a set cap. Many
+numbers hit the cap, some numbers are not syntactically correct.
+
+ ./perf numparser [loops]
+
## `simpleformat`
This test repeatedly formats a commonly used simple message with
tests/perf/numparser.c+239 -0
@@ -0,0 +1,239 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "first.h"
+
+struct num {
+ const char *str;
+ int base;
+ curl_off_t max;
+};
+
+static const struct num nums[] = {
+ { "9223372036854775807", 10, 9223372036854775807LL },
+ { "123456789123456123A", 10, 9223372036854775807LL },
+ { "123456789123456123B", 10, 9223372036854775807LL },
+ { "123456789123456123C", 10, 9223372036854775807LL },
+ { "123456789123456123D", 10, 9223372036854775807LL },
+ { "1234567891234561234", 10, 9223372036854775807LL },
+ { "123456789123456123", 10, 9223372036854775807LL },
+ { "12345678912345612", 10, 9223372036854775807LL },
+ { "1234567891234561", 10, 9223372036854775807LL },
+ { "123456789123456", 10, 9223372036854775807LL },
+ { "12345678912345", 10, 9223372036854775807LL },
+ { "1234567891234", 10, 9223372036854775807LL },
+ { "123456789123", 10, 9223372036854775807LL },
+ { "12345678912", 10, 9223372036854775807LL },
+ { "1234567891", 10, 9223372036854775807LL },
+ { "123456789", 10, 9223372036854775807LL },
+ { "12345678", 10, 9223372036854775807LL },
+ { "1234567", 10, 9223372036854775807LL },
+ { "123456", 10, 9223372036854775807LL },
+ { "12345", 10, 9223372036854775807LL },
+ { "1234", 10, 9223372036854775807LL },
+ { "123", 10, 9223372036854775807LL },
+ { "12", 10, 9223372036854775807LL },
+ { "1", 10, 9223372036854775807 },
+ { "9223372036854775807", 10, 9223372036854775806LL },
+ { "1234567891234561234", 10, 1234567891234561233LL },
+ { "234567891234561234", 10, 234567891234561233LL },
+ { "34567891234561234", 10, 34567891234561233LL },
+ { "4567891234561234", 10, 4567891234561233LL },
+ { "567891234561234", 10, 567891234561233LL },
+ { "67891234561234", 10, 67891234561233LL },
+ { "7891234561234", 10, 7891234561233LL },
+ { "891234561234", 10, 891234561233LL },
+ { "91234561234", 10, 91234561233LL },
+ { "1234561234", 10, 1234561233LL },
+ { "234561234", 10, 234561233LL },
+ { "34561234", 10, 34561233LL },
+ { "4561234", 10, 4561233LL },
+
+ { "7FFFFFFFFFFFFFFF", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFFF", 16, 0x7FFFFFFFFFFFFFFELL },
+ { "7FFFFFFFFFFFFFFF", 16, 0x7FFFFFFFFFFFFFFDLL },
+ { "7FFFFFFFFFFFFFFF", 16, 0x7FFFFFFFFFFFFFFCLL },
+ { "7FFFFFFFFFFFFFFF", 16, 0x7FFFFFFFFFFFFFFBLL },
+ { "7FFFFFFFFFFFFFFE", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFFD", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFFC", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFFB", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFFA", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFF9", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "7FFFFFFFFFFFFFFG", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "GFFFFFFFFFFFFFF9", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "HFFFFFFFFFFFFFF9", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "IFFFFFFFFFFFFFF9", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "KFFFFFFFFFFFFFF9", 16, 0x7FFFFFFFFFFFFFFFLL },
+ { "1234567890123456", 16, 0x1234567890123456LL },
+ { "123456789012345G", 16, 0x1234567890123456LL },
+ { "123456789012345H", 16, 0x1234567890123456LL },
+ { "123456789012345I", 16, 0x1234567890123456LL },
+ { "123456789012345J", 16, 0x1234567890123456LL },
+ { "123456789012345K", 16, 0x1234567890123456LL },
+ { "234567890123456", 16, 0x1234567890123456LL },
+ { "34567890123456", 16, 0x1234567890123456LL },
+ { "4567890123456", 16, 0x1234567890123456LL },
+ { "567890123456", 16, 0x1234567890123456LL },
+ { "567890123456", 16, 0x1234567890123456LL },
+ { "67890123456", 16, 0x1234567890123456LL },
+ { "7890123456", 16, 0x1234567890123456LL },
+ { "890123456", 16, 0x1234567890123456LL },
+ { "90123456", 16, 0x1234567890123456LL },
+ { "0123456", 16, 0x1234567890123456LL },
+ { "123456", 16, 0x1234567890123456LL },
+ { "23456", 16, 0x1234567890123456LL },
+ { "3456", 16, 0x1234567890123456LL },
+ { "456", 16, 0x1234567890123456LL },
+ { "56", 16, 0x1234567890123456LL },
+ { "6", 16, 0x1234567890123456LL },
+
+ { "1234567890123456", 16, 0x1234567890123455LL },
+ { "234567890123456", 16, 0x234567890123455LL },
+ { "34567890123456", 16, 0x34567890123455LL },
+ { "4567890123456", 16, 0x4567890123455LL },
+ { "67890123456", 16, 0x67890123455LL },
+ { "7890123456", 16, 0x7890123455LL },
+ { "890123456", 16, 0x890123455LL },
+ { "90123456", 16, 0x90123455LL },
+ { "0123456", 16, 0x0123455LL },
+ { "123456", 16, 0x123455LL },
+ { "23456", 16, 0x23455LL },
+
+ { "10", 10, 5 },
+ { "9", 10, 5 },
+ { "8", 10, 5 },
+ { "7", 10, 5 },
+ { "3", 10, 5 },
+ { "2", 10, 5 },
+ { "1", 10, 5 },
+
+ { "10", 16, 8 },
+ { "9", 16, 8 },
+ { "8", 16, 8 },
+ { "7", 16, 6 },
+ { "3", 16, 7 },
+ { "2", 16, 5 },
+ { "1", 16, 5 },
+
+ {"777777777777777777777", 8, 0777777777777777777777LL },
+ {"777777777777777777776", 8, 0777777777777777777777LL },
+ {"777777777777777777775", 8, 0777777777777777777777LL },
+ {"777777777777777777774", 8, 0777777777777777777777LL },
+ {"777777777777777777773", 8, 0777777777777777777777LL },
+ {"777777777777777777772", 8, 0777777777777777777777LL },
+ {"777777777777777777779", 8, 0777777777777777777777LL },
+ {"123456701234567012345", 8, 0123456701234567012345LL },
+ {"12345670123456701234", 8, 0123456701234567012345LL },
+ {"1234567012345670123", 8, 0123456701234567012345LL },
+ {"123456701234567012", 8, 0123456701234567012345LL },
+ {"12345670123456701", 8, 0123456701234567012345LL },
+ {"1234567012345670", 8, 0123456701234567012345LL },
+ {"123456701234567", 8, 0123456701234567012345LL },
+ {"12345670123456", 8, 0123456701234567012345LL },
+ {"1234567012345", 8, 0123456701234567012345LL },
+ {"123456701234", 8, 0123456701234567012345LL },
+ {"12345670123", 8, 0123456701234567012345LL },
+ {"1234567012", 8, 0123456701234567012345LL },
+ {"123456701", 8, 0123456701234567012345LL },
+
+ {"123456701234567012345", 8, 0123456701234567012344LL },
+ {"23456701234567012345", 8, 023456701234567012344LL },
+ {"3456701234567012345", 8, 03456701234567012344LL },
+ {"456701234567012345", 8, 0456701234567012344LL },
+ {"56701234567012345", 8, 056701234567012344LL },
+ {"6701234567012345", 8, 06701234567012344LL },
+ {"701234567012345", 8, 0701234567012344LL },
+ {"01234567012345", 8, 01234567012344LL },
+ {"1234567012345", 8, 01234567012344LL },
+ {"234567012345", 8, 0234567012344LL },
+ {"34567012345", 8, 034567012344LL },
+ {"4567012345", 8, 04567012344LL },
+ {"567012345", 8, 0567012344LL },
+ {"67012345", 8, 067012344LL },
+
+ {"123456701234567012348", 8, 0123456701234567012344LL },
+ {"123456701234567012349", 8, 0123456701234567012344LL },
+ {"12345670123456701234A", 8, 0123456701234567012344LL },
+ {"12345670123456701234C", 8, 0123456701234567012344LL },
+ {"12345670123456701234B", 8, 0123456701234567012344LL },
+
+};
+
+/*
+ * Parse the numbers
+ */
+static int test_numparser(int argc, const char **argv)
+{
+ struct curltime start;
+ struct curltime end;
+ timediff_t us;
+ long long hn;
+ curl_off_t loops = 500000, loop;
+ curl_off_t count = 0;
+ curl_off_t ecount = 0; /* errors */
+ size_t i;
+ size_t nnumbers = CURL_ARRAYSIZE(nums);
+
+ if(argc > 1) {
+ const char *ptr = argv[1];
+ curl_off_t num;
+ if(!curlx_str_number(&ptr, &num, INT_MAX) && !*ptr)
+ loops = num;
+ }
+
+ curl_mprintf("Found %zu numbers to parse\n", nnumbers);
+
+ start = curlx_now();
+ for(loop = 0; loop < loops; loop++) {
+ for(i = 0; i < nnumbers; i++) {
+ const char *p = nums[i].str;
+ curl_off_t val;
+ int err;
+ if(nums[i].base == 10)
+ err = curlx_str_number(&p, &val, nums[i].max);
+ else if(nums[i].base == 16)
+ err = curlx_str_hex(&p, &val, nums[i].max);
+ else
+ err = curlx_str_octal(&p, &val, nums[i].max);
+ if(err)
+ ecount++;
+ count++;
+ }
+ }
+ end = curlx_now();
+ us = curlx_timediff_us(end, start); /* how many microseconds */
+ hn = count ? us * 1000000 / count : 0; /* 1000 times too big */
+ curl_mprintf("Numbers: %" CURL_FORMAT_CURL_OFF_T "\n"
+ "Time: %lld usecs\n"
+ "Time/num: %lld.%03lld ns\n"
+ "Nums/sec: %lld\n"
+ "Errors: %" CURL_FORMAT_CURL_OFF_T "\n",
+ count,
+ (long long)us,
+ (long long)hn / 1000,
+ (long long)hn % 1000,
+ us ? (long long)(count * 1000000) / us : 0,
+ ecount);
+ return 0;
+}