perf-numparser: add number parsing performance test
No binary (build failed)
—
(log yok)
| @@ -47,6 +47,7 @@ TESTS_C = \ | |
| base64enc.c \ | |
| dateparser.c \ | |
| maprintf.c \ | |
| + | numparser.c \ |
| simpleformat.c \ | |
| snprintf.c \ | |
| urldecode.c \ | |
| @@ -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 | |
| @@ -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; |
| + | } |