build: add performance tests
No binary (build failed)
—
(log yok)
| @@ -5557,12 +5557,13 @@ AC_CONFIG_FILES([\ | |
| tests/configurehelp.pm \ | |
| tests/certs/Makefile \ | |
| tests/data/Makefile \ | |
| - | tests/server/Makefile \ |
| - | tests/libtest/Makefile \ |
| - | tests/unit/Makefile \ |
| - | tests/tunit/Makefile \ |
| tests/http/config.ini \ | |
| tests/http/Makefile \ | |
| + | tests/libtest/Makefile \ |
| + | tests/perf/Makefile \ |
| + | tests/server/Makefile \ |
| + | tests/tunit/Makefile \ |
| + | tests/unit/Makefile \ |
| projects/Makefile \ | |
| projects/vms/Makefile | |
| ]) | |
| @@ -49,6 +49,7 @@ add_custom_target(testdeps) | |
| add_dependencies(testdeps "tt") | |
| add_subdirectory(http) | |
| + | add_subdirectory(perf) |
| add_subdirectory(server) | |
| add_subdirectory(libtest) | |
| if(BUILD_CURL_EXE) | |
| @@ -95,7 +95,7 @@ BUILD_UNIT = | |
| DIST_UNIT = unit tunit | |
| endif | |
| - | SUBDIRS = certs data server libtest http $(BUILD_UNIT) |
| + | SUBDIRS = certs data perf server libtest http $(BUILD_UNIT) |
| DIST_SUBDIRS = $(SUBDIRS) $(DIST_UNIT) | |
| PERLFLAGS = -I$(srcdir) | |
| @@ -177,9 +177,10 @@ ci-pytest: all | |
| checksrc: | |
| (cd libtest && $(MAKE) checksrc) | |
| - | (cd unit && $(MAKE) checksrc) |
| - | (cd tunit && $(MAKE) checksrc) |
| + | (cd perf && $(MAKE) checksrc) |
| (cd server && $(MAKE) checksrc) | |
| + | (cd tunit && $(MAKE) checksrc) |
| + | (cd unit && $(MAKE) checksrc) |
| all-local: build-certs | |
| @@ -56,19 +56,18 @@ CFLAGS += @CURL_CFLAG_EXTRAS@ | |
| # Prevent LIBS from being used for all link targets | |
| LIBS = $(BLANK_AT_MAKETIME) | |
| - | if USE_CPPFLAG_CURL_STATICLIB |
| - | AM_CPPFLAGS += -DCURL_STATICLIB |
| - | endif |
| if DEBUGBUILD | |
| AM_CPPFLAGS += -DDEBUGBUILD | |
| endif | |
| if USE_CPPFLAG_CURL_STATICLIB | |
| + | AM_CPPFLAGS += -DCURL_STATICLIB |
| curlx_c_lib = | |
| else | |
| # These are part of the libcurl static lib. Add them here when linking shared. | |
| curlx_c_lib = $(CURLX_C) | |
| endif | |
| + | |
| $(BUNDLE).c: $(top_srcdir)/scripts/mk-unity.pl Makefile.inc $(FIRST_C) $(UTILS_C) $(curlx_c_lib) $(TOOLX_C) $(TESTS_C) lib1521.c | |
| @PERL@ $(top_srcdir)/scripts/mk-unity.pl --include $(UTILS_C) $(curlx_c_lib) $(TOOLX_C) --test $(TESTS_C) lib1521.c > $(BUNDLE).c | |
| @@ -0,0 +1,6 @@ | |
| + | # Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | # |
| + | # SPDX-License-Identifier: curl |
| + | |
| + | perf |
| + | perf.c |
| @@ -0,0 +1,59 @@ | |
| + | #*************************************************************************** |
| + | # _ _ ____ _ |
| + | # 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 |
| + | # |
| + | ########################################################################### |
| + | |
| + | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TOOLX_C, TESTS_C variables |
| + | curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") |
| + | include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") |
| + | |
| + | if(LIB_SELECTED STREQUAL LIB_STATIC) |
| + | set(CURLX_C "") # Already exported from the libcurl static build. Skip them. |
| + | endif() |
| + | |
| + | if(_CURL_TESTS_CONCAT) |
| + | set(_mk_unity_extra "--concat" "-I${CMAKE_CURRENT_SOURCE_DIR}") |
| + | endif() |
| + | |
| + | add_custom_command(OUTPUT "${BUNDLE}.c" |
| + | COMMAND ${PERL_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/mk-unity.pl" ${_mk_unity_extra} |
| + | --include ${UTILS_C} ${CURLX_C} ${TOOLX_C} --test ${TESTS_C} > "${BUNDLE}.c" |
| + | DEPENDS |
| + | "${PROJECT_SOURCE_DIR}/scripts/mk-unity.pl" "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.inc" |
| + | ${FIRST_C} ${FIRST_H} ${UTILS_C} ${CURLX_C} ${TOOLX_C} ${TESTS_C} |
| + | VERBATIM) |
| + | |
| + | add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") |
| + | add_dependencies(tt ${BUNDLE}) |
| + | target_link_libraries(${BUNDLE} ${LIB_SELECTED} ${CURL_LIBS}) |
| + | target_include_directories(${BUNDLE} PRIVATE |
| + | "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" |
| + | "${PROJECT_SOURCE_DIR}/lib" # for "curl_setup.h", curlx |
| + | "${PROJECT_SOURCE_DIR}/src" # for toolx |
| + | "${CMAKE_CURRENT_SOURCE_DIR}" # for the generated bundle source to find included test sources |
| + | ) |
| + | set_target_properties(${BUNDLE} PROPERTIES OUTPUT_NAME "${BUNDLE}" PROJECT_LABEL "Test ${BUNDLE}" UNITY_BUILD OFF) |
| + | |
| + | if(NOT _CURL_TESTS_CONCAT) |
| + | set_target_properties(${BUNDLE} PROPERTIES C_CLANG_TIDY "") |
| + | curl_add_clang_tidy_test_target("${BUNDLE}-clang-tidy" ${BUNDLE} ${FIRST_C} ${UTILS_C} ${TESTS_C}) |
| + | endif() |
| @@ -0,0 +1,82 @@ | |
| + | #*************************************************************************** |
| + | # _ _ ____ _ |
| + | # 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 |
| + | # |
| + | ########################################################################### |
| + | AUTOMAKE_OPTIONS = foreign nostdinc |
| + | |
| + | # Specify our include paths here, and do it relative to $(top_srcdir) and |
| + | # $(top_builddir), to ensure that these paths which belong to the library |
| + | # being currently built and tested are searched before the library which |
| + | # might possibly already be installed in the system. |
| + | # |
| + | # $(top_srcdir)/include is for libcurl's external include files |
| + | # $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file |
| + | # $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files |
| + | # $(top_srcdir)/src for toolx header files |
| + | # $(srcdir) for the generated bundle source to find included test sources |
| + | |
| + | AM_CPPFLAGS = -I$(top_srcdir)/include \ |
| + | -I$(top_builddir)/lib \ |
| + | -I$(top_srcdir)/lib \ |
| + | -I$(top_srcdir)/src \ |
| + | -I$(srcdir) |
| + | |
| + | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TOOLX_C, TESTS_C variables |
| + | include Makefile.inc |
| + | |
| + | EXTRA_DIST = CMakeLists.txt README.md $(FIRST_C) $(FIRST_H) $(UTILS_C) $(UTILS_H) $(TESTS_C) |
| + | |
| + | CFLAGS += @CURL_CFLAG_EXTRAS@ |
| + | |
| + | # Prevent LIBS from being used for all link targets |
| + | LIBS = $(BLANK_AT_MAKETIME) |
| + | |
| + | if USE_CPPFLAG_CURL_STATICLIB |
| + | AM_CPPFLAGS += -DCURL_STATICLIB |
| + | curlx_c_lib = |
| + | else |
| + | # These are part of the libcurl static lib. Add them here when linking shared. |
| + | curlx_c_lib = $(CURLX_C) |
| + | endif |
| + | |
| + | $(BUNDLE).c: $(top_srcdir)/scripts/mk-unity.pl Makefile.inc $(FIRST_C) $(UTILS_C) $(curlx_c_lib) $(TOOLX_C) $(TESTS_C) |
| + | @PERL@ $(top_srcdir)/scripts/mk-unity.pl --include $(UTILS_C) $(curlx_c_lib) $(TOOLX_C) --test $(TESTS_C) > $(BUNDLE).c |
| + | |
| + | noinst_PROGRAMS = $(BUNDLE) |
| + | nodist_perf_SOURCES = $(BUNDLE).c |
| + | LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ |
| + | CLEANFILES = $(BUNDLE).c |
| + | |
| + | CHECKSRC = $(CS_$(V)) |
| + | CS_0 = @echo " RUN " $@; |
| + | CS_1 = |
| + | CS_ = $(CS_0) |
| + | |
| + | checksrc: |
| + | $(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) -W$(srcdir)/$(BUNDLE).c $(FIRST_C) $(FIRST_H) $(UTILS_C) $(UTILS_H) $(TESTS_C)) |
| + | |
| + | if NOT_CURL_CI |
| + | all-local: checksrc |
| + | endif |
| + | |
| + | clean-local: |
| + | rm -f $(BUNDLE) |
| @@ -0,0 +1,48 @@ | |
| + | #*************************************************************************** |
| + | # _ _ ____ _ |
| + | # 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 |
| + | # |
| + | ########################################################################### |
| + | # Shared between CMakeLists.txt and Makefile.am |
| + | |
| + | BUNDLE = perf |
| + | |
| + | # Files referenced from the bundle source |
| + | FIRST_C = first.c |
| + | FIRST_H = first.h |
| + | |
| + | # Common files used by the performance test programs |
| + | UTILS_C = |
| + | UTILS_H = |
| + | |
| + | CURLX_C = \ |
| + | ../../lib/curlx/base64.c \ |
| + | ../../lib/curlx/fopen.c \ |
| + | ../../lib/curlx/multibyte.c \ |
| + | ../../lib/curlx/strparse.c \ |
| + | ../../lib/curlx/timeval.c \ |
| + | ../../lib/curlx/warnless.c |
| + | |
| + | # All performance test programs |
| + | TESTS_C = \ |
| + | base64.c \ |
| + | snprintf.c \ |
| + | urlparser.c |
| @@ -0,0 +1,36 @@ | |
| + | <!-- |
| + | Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | |
| + | SPDX-License-Identifier: curl |
| + | --> |
| + | |
| + | # Performance tests |
| + | |
| + | This directory contains small stand-alone libcurl-using programs that each |
| + | test specific aspects of the library's performance. |
| + | |
| + | The idea is to have a set of tests here that can be used to verify various |
| + | libcurl functions' performance when we have no other good means of doing so. |
| + | Performance is best tested relatively. Does it run slower or faster than |
| + | before? |
| + | |
| + | Ideally these tests run without using any servers. |
| + | |
| + | ## `urlparser` |
| + | |
| + | Provide this test with a list of many URLs and it times how fast it can parse |
| + | them: `./perf urlparser URLs.txt [loops]` |
| + | |
| + | A test sample of 100K URLs can be found |
| + | [here](https://raw.githubusercontent.com/ada-url/url-various-datasets/refs/heads/main/top100/top100.txt) |
| + | |
| + | ## `base64` |
| + | |
| + | This test first base64 encodes a 256-byte buffer that has every different |
| + | byte octet represented. It then decodes that string. Repeatedly in a loop the |
| + | provided number of times: `./perf base64 [loops]` |
| + | |
| + | ## `snprintf` |
| + | |
| + | This test repeatedly formats a representative string and measures the time per |
| + | call: `./perf snprintf [loops]` |
| @@ -0,0 +1,79 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * 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" |
| + | |
| + | static int test_base64(int argc, const char **argv) |
| + | { |
| + | struct curltime start; |
| + | struct curltime end; |
| + | timediff_t us; |
| + | long long hn; |
| + | |
| + | curl_off_t loops = 10000000, loop; |
| + | |
| + | unsigned char array[256]; |
| + | unsigned int c; |
| + | |
| + | if(argc > 1) { |
| + | const char *ptr = argv[1]; |
| + | curl_off_t num; |
| + | if(!curlx_str_number(&ptr, &num, CURL_OFF_T_MAX) && !*ptr) |
| + | loops = num; |
| + | } |
| + | |
| + | for(c = 0; c < 256; c++) { |
| + | array[c] = (unsigned char)c; |
| + | } |
| + | |
| + | start = curlx_now(); |
| + | for(loop = 0; loop < loops; loop++) { |
| + | char *encoded; |
| + | size_t enclen; |
| + | CURLcode result = |
| + | curlx_base64_encode(array, sizeof(array), &encoded, &enclen); |
| + | if(!result) { |
| + | unsigned char *recoded = NULL; |
| + | size_t reclen; |
| + | /* now decode it again */ |
| + | result = curlx_base64_decode(encoded, &recoded, &reclen); |
| + | curlx_free(recoded); |
| + | } |
| + | if(result) { |
| + | curl_mfprintf(stderr, "unexpected coding error: %d\n", (int)result); |
| + | return 1; |
| + | } |
| + | curlx_free(encoded); |
| + | } |
| + | end = curlx_now(); |
| + | us = curlx_timediff_us(end, start); /* how many microseconds */ |
| + | hn = loop ? us * 100000 / loops : 0; /* 100 times too big */ |
| + | curl_mprintf("Loops: %" CURL_FORMAT_CURL_OFF_T "\n" |
| + | "Time: %lld usecs\n" |
| + | "Time/loop: %lld.%lld ns\n", |
| + | loops, |
| + | (long long)us, |
| + | (long long)hn / 100, |
| + | (long long)hn % 100); |
| + | return 0; |
| + | } |
| @@ -0,0 +1,67 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * 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" |
| + | |
| + | #ifdef _WIN32 |
| + | static void win32_cleanup(void) |
| + | { |
| + | _flushall(); /* flush buffers of all streams regardless of their mode */ |
| + | } |
| + | #endif |
| + | |
| + | int main(int argc, const char *argv[]) |
| + | { |
| + | entry_func_t entry_func; |
| + | const char *entry_name; |
| + | int result; |
| + | size_t tmp; |
| + | |
| + | if(argc < 2) { |
| + | curl_mfprintf(stderr, "Pass perftest as first argument\n"); |
| + | return 1; |
| + | } |
| + | |
| + | entry_name = argv[1]; |
| + | entry_func = NULL; |
| + | for(tmp = 0; s_entries[tmp].ptr; ++tmp) { |
| + | if(!strcmp(entry_name, s_entries[tmp].name)) { |
| + | entry_func = s_entries[tmp].ptr; |
| + | break; |
| + | } |
| + | } |
| + | |
| + | if(!entry_func) { |
| + | curl_mfprintf(stderr, "Test '%s' not found.\n", entry_name); |
| + | return 99; |
| + | } |
| + | |
| + | #ifdef _WIN32 |
| + | curlx_now_init(); |
| + | atexit(win32_cleanup); |
| + | #endif |
| + | |
| + | result = entry_func(argc - 1, argv + 1); |
| + | |
| + | return result; |
| + | } |
| @@ -0,0 +1,56 @@ | |
| + | #ifndef HEADER_PERF_FIRST_H |
| + | #define HEADER_PERF_FIRST_H |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * 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 |
| + | * |
| + | ***************************************************************************/ |
| + | #define CURL_NO_OLDIES |
| + | #define CURL_DISABLE_DEPRECATION |
| + | |
| + | /* Now include the curl_setup.h file from libcurl's private libdir (the source |
| + | version, but that might include "curl_config.h" from the build directory so |
| + | we need both of them in the include path), so that we get good in-depth |
| + | knowledge about the system we are building this on */ |
| + | #include "curl_setup.h" |
| + | |
| + | #include "curlx/base64.h" /* for curlx_base64* */ |
| + | #include "curlx/fopen.h" /* for curlx_f*() */ |
| + | #include "curlx/strparse.h" /* for curlx_str_* parsing functions */ |
| + | #include "curlx/timeval.h" /* for curlx_now type and related functions */ |
| + | |
| + | #ifdef HAVE_FCNTL_H |
| + | #include <fcntl.h> |
| + | #endif |
| + | #ifdef HAVE_UNISTD_H |
| + | #include <unistd.h> |
| + | #endif |
| + | |
| + | typedef int (*entry_func_t)(int, const char **); |
| + | |
| + | struct entry_s { |
| + | const char *name; |
| + | entry_func_t ptr; |
| + | }; |
| + | |
| + | extern const struct entry_s s_entries[]; |
| + | |
| + | #endif /* HEADER_PERF_FIRST_H */ |
| @@ -0,0 +1,67 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * 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" |
| + | |
| + | static int test_snprintf(int argc, const char **argv) |
| + | { |
| + | struct curltime start; |
| + | struct curltime end; |
| + | timediff_t us; |
| + | long long hn; |
| + | |
| + | curl_off_t loops = 10000000, loop; |
| + | |
| + | char buffer[256]; |
| + | |
| + | if(argc > 1) { |
| + | const char *ptr = argv[1]; |
| + | curl_off_t num; |
| + | if(!curlx_str_number(&ptr, &num, CURL_OFF_T_MAX) && !*ptr) |
| + | loops = num; |
| + | } |
| + | |
| + | start = curlx_now(); |
| + | for(loop = 0; loop < loops; loop++) { |
| + | curl_msnprintf(buffer, sizeof(buffer), |
| + | "Add %-4d stuff %u to %3d the %3u output %s " |
| + | "%*s" |
| + | "for %lld testing %lu\n", |
| + | 123, (unsigned int)123, |
| + | 123, (unsigned int)123, "helllo", |
| + | 14, "01234567890123456", |
| + | (long long)987871231231, |
| + | (unsigned long)6732673); |
| + | } |
| + | end = curlx_now(); |
| + | us = curlx_timediff_us(end, start); /* how many microseconds */ |
| + | hn = loops ? us * 100000 / loops : 0; /* 100 times too big */ |
| + | curl_mprintf("Loops: %" CURL_FORMAT_CURL_OFF_T "\n" |
| + | "Time: %lld usecs\n" |
| + | "Time/loop: %lld.%lld ns\n", |
| + | loops, |
| + | (long long)us, |
| + | (long long)hn / 100, |
| + | (long long)hn % 100); |
| + | return 0; |
| + | } |
| @@ -0,0 +1,171 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * 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" |
| + | |
| + | /* |
| + | * Read many URLs from a given file. |
| + | * Parse them with all listed option combinations |
| + | */ |
| + | static int test_urlparser(int argc, const char **argv) |
| + | { |
| + | static const int options[] = { |
| + | CURLU_DEFAULT_PORT, |
| + | CURLU_DEFAULT_SCHEME, |
| + | CURLU_NON_SUPPORT_SCHEME, |
| + | CURLU_ALLOW_SPACE, |
| + | CURLU_GUESS_SCHEME, |
| + | CURLU_PATH_AS_IS, |
| + | CURLU_DISALLOW_USER |
| + | }; |
| + | |
| + | static char *urls[150000]; |
| + | |
| + | struct curltime start; |
| + | struct curltime end; |
| + | timediff_t us; |
| + | long long hn; |
| + | |
| + | curl_off_t loops = 10, loop; |
| + | |
| + | curl_off_t count = 0; |
| + | curl_off_t ecount = 0; /* errors */ |
| + | |
| + | int ret; |
| + | size_t o; |
| + | int fd; |
| + | char *buffer = NULL; |
| + | size_t i; |
| + | size_t nsize; |
| + | ssize_t nread; |
| + | size_t nurls = 0; /* number of URLs */ |
| + | curlx_struct_stat info; |
| + | char *p; |
| + | CURLU *uh; |
| + | |
| + | if(argc < 2) { |
| + | curl_mfprintf(stderr, "%s <URL file> [iterations]\n", argv[0]); |
| + | return 2; |
| + | } |
| + | if(argc > 2) { |
| + | const char *ptr = argv[2]; |
| + | curl_off_t num; |
| + | if(!curlx_str_number(&ptr, &num, 100000) && !*ptr) |
| + | loops = num; |
| + | } |
| + | |
| + | fd = curlx_open(argv[1], O_RDONLY | CURL_O_BINARY); |
| + | if(fd == -1) { |
| + | curl_mfprintf(stderr, "Cannot open %s, exiting\n", argv[1]); |
| + | return 3; |
| + | } |
| + | |
| + | if(curlx_fstat(fd, &info) == -1) { |
| + | curlx_close(fd); |
| + | curl_mfprintf(stderr, "Cannot stat %s, exiting\n", argv[1]); |
| + | return 3; |
| + | } |
| + | |
| + | ret = 4; |
| + | |
| + | nsize = (size_t)info.st_size; |
| + | |
| + | buffer = curlx_malloc(nsize + 1); |
| + | if(!buffer) { |
| + | curlx_close(fd); |
| + | curl_mfprintf(stderr, "Cannot malloc the buffer\n"); |
| + | goto cleanup; |
| + | } |
| + | |
| + | nread = read(fd, buffer, nsize); |
| + | curlx_close(fd); |
| + | if(nread != (ssize_t)nsize) { |
| + | curl_mfprintf(stderr, "Cannot load the file\n"); |
| + | goto cleanup; |
| + | } |
| + | |
| + | buffer[nsize] = 0; |
| + | p = buffer; |
| + | while(*p) { |
| + | if(nurls >= CURL_ARRAYSIZE(urls)) { |
| + | curl_mfprintf(stderr, |
| + | "Too many URLs in file, rebuild with higher max\n"); |
| + | goto cleanup; |
| + | } |
| + | urls[nurls++] = p; |
| + | p = strchr(p, '\n'); |
| + | if(!p) |
| + | break; |
| + | if(p > urls[nurls - 1] && p[-1] == '\r') |
| + | p[-1] = '\0'; |
| + | *p = '\0'; |
| + | p++; |
| + | } |
| + | curl_mprintf("Found %zu URLs to test for %" CURL_FORMAT_CURL_OFF_T |
| + | " iterations (%zu variations)\n", |
| + | nurls, loops, CURL_ARRAYSIZE(options)); |
| + | |
| + | uh = curl_url(); |
| + | if(!uh) { |
| + | curl_mfprintf(stderr, "curl_url() failed\n"); |
| + | goto cleanup; |
| + | } |
| + | start = curlx_now(); |
| + | for(loop = 0; loop < loops; loop++) { |
| + | for(i = 0; i < nurls; i++) { |
| + | for(o = 0; o < CURL_ARRAYSIZE(options); o++) { |
| + | CURLUcode hcode = curl_url_set(uh, CURLUPART_URL, urls[i], options[o]); |
| + | count++; |
| + | if(hcode) { |
| + | #if 0 |
| + | curl_mfprintf(stderr, "Failed [%u]: %s\n", (int)hcode, buffer); |
| + | #endif |
| + | ecount++; |
| + | } |
| + | } |
| + | } |
| + | } |
| + | end = curlx_now(); |
| + | curl_url_cleanup(uh); |
| + | us = curlx_timediff_us(end, start); /* how many microseconds */ |
| + | hn = count ? us * 100000 / count : 0; /* 100 times too big */ |
| + | curl_mprintf("URLs: %" CURL_FORMAT_CURL_OFF_T "\n" |
| + | "Time: %lld usecs\n" |
| + | "Time/URL: %lld.%lld ns\n" |
| + | "URLs/sec: %lld\n" |
| + | "Errors: %" CURL_FORMAT_CURL_OFF_T "\n", |
| + | count, |
| + | (long long)us, |
| + | (long long)hn / 100, |
| + | (long long)hn % 100, |
| + | us ? (long long)(count * 1000000) / us : 0, |
| + | ecount); |
| + | |
| + | ret = 0; |
| + | |
| + | cleanup: |
| + | |
| + | curlx_free(buffer); |
| + | |
| + | return ret; |
| + | } |