"Fossies" - the Fresh Open Source Software Archive

Member "xxHash-0.8.0/tests/bench/main.c" (27 Jul 2020, 7438 Bytes) of package /linux/misc/xxHash-0.8.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "main.c": 0.7.3_vs_0.7.4.

    1 /*
    2  * Main program to benchmark hash functions
    3  * Part of the xxHash project
    4  * Copyright (C) 2019-2020 Yann Collet
    5  * GPL v2 License
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
   10  * (at your option) any later version.
   11  *
   12  * This program is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU General Public License along
   18  * with this program; if not, write to the Free Software Foundation, Inc.,
   19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   20  *
   21  * You can contact the author at:
   22  * - xxHash homepage: https://www.xxhash.com
   23  * - xxHash source repository: https://github.com/Cyan4973/xxHash
   24  */
   25 
   26 
   27 /* ===  dependencies  === */
   28 
   29 #include <stdio.h>       /* printf */
   30 #include <limits.h>      /* INT_MAX */
   31 #include "bhDisplay.h"   /* bench_x */
   32 
   33 
   34 /* ===  defines list of hashes `hashCandidates` and NB_HASHES  *** */
   35 
   36 #include "hashes.h"
   37 
   38 
   39 /* ===  parse command line  === */
   40 
   41 #undef NDEBUG
   42 #include <assert.h>
   43 
   44 
   45 /*!
   46  * readIntFromChar():
   47  * Allows and interprets K, KB, KiB, M, MB and MiB suffix.
   48  * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
   49  */
   50 static int readIntFromChar(const char** stringPtr)
   51 {
   52     static int const max = (INT_MAX / 10) - 1;
   53     int result = 0;
   54     while ((**stringPtr >='0') && (**stringPtr <='9')) {
   55         assert(result < max);
   56         result *= 10;
   57         result += (unsigned)(**stringPtr - '0');
   58         (*stringPtr)++ ;
   59     }
   60     if ((**stringPtr=='K') || (**stringPtr=='M')) {
   61         int const maxK = INT_MAX >> 10;
   62         assert(result < maxK);
   63         result <<= 10;
   64         if (**stringPtr=='M') {
   65             assert(result < maxK);
   66             result <<= 10;
   67         }
   68         (*stringPtr)++;  /* skip `K` or `M` */
   69         if (**stringPtr=='i') (*stringPtr)++;
   70         if (**stringPtr=='B') (*stringPtr)++;
   71     }
   72     return result;
   73 }
   74 
   75 
   76 /**
   77  * longCommand():
   78  * Checks if string is the same as longCommand.
   79  * If yes, @return 1, otherwise @return 0
   80  */
   81 static int isCommand(const char* string, const char* longCommand)
   82 {
   83     assert(string);
   84     assert(longCommand);
   85     size_t const comSize = strlen(longCommand);
   86     return !strncmp(string, longCommand, comSize);
   87 }
   88 
   89 /*
   90  * longCommandWArg():
   91  * Checks if *stringPtr is the same as longCommand.
   92  * If yes, @return 1 and advances *stringPtr to the position which immediately
   93  * follows longCommand.
   94  * @return 0 and doesn't modify *stringPtr otherwise.
   95  */
   96 static int longCommandWArg(const char** stringPtr, const char* longCommand)
   97 {
   98     assert(stringPtr);
   99     assert(longCommand);
  100     size_t const comSize = strlen(longCommand);
  101     int const result = isCommand(*stringPtr, longCommand);
  102     if (result) *stringPtr += comSize;
  103     return result;
  104 }
  105 
  106 
  107 /* ===   default values - can be redefined at compilation time   === */
  108 
  109 #ifndef SMALL_SIZE_MIN_DEFAULT
  110 #  define SMALL_SIZE_MIN_DEFAULT   1
  111 #endif
  112 #ifndef SMALL_SIZE_MAX_DEFAULT
  113 #  define SMALL_SIZE_MAX_DEFAULT 127
  114 #endif
  115 #ifndef LARGE_SIZELOG_MIN_DEFAULT
  116 #  define LARGE_SIZELOG_MIN_DEFAULT   9
  117 #endif
  118 #ifndef LARGE_SIZELOG_MAX_DEFAULT
  119 #  define LARGE_SIZELOG_MAX_DEFAULT  27
  120 #endif
  121 
  122 
  123 static int display_hash_names(void)
  124 {
  125     int i;
  126     printf("available hashes : \n");
  127     for (i=0; i<NB_HASHES; i++) {
  128         printf("%s, ", hashCandidates[i].name);
  129     }
  130     printf("\b\b  \n");
  131     return 0;
  132 }
  133 
  134 /*
  135  * @return: hashID (necessarily between 0 and NB_HASHES) if present
  136  *          -1 on error (hname not present)
  137  */
  138 static int hashID(const char* hname)
  139 {
  140     int id;
  141     assert(hname);
  142     for (id=0; id < NB_HASHES; id++) {
  143         assert(hashCandidates[id].name);
  144         if (strlen(hname) != strlen(hashCandidates[id].name)) continue;
  145         if (isCommand(hname, hashCandidates[id].name)) return id;
  146     }
  147     return -1;
  148 }
  149 
  150 static int help(const char* exename)
  151 {
  152     printf("Usage: %s [options]... [hash]\n", exename);
  153     printf("Runs various benchmarks at various lengths for the listed hash functions\n");
  154     printf("and outputs them in a CSV format.\n\n");
  155     printf("Options: \n");
  156     printf("  --list       Name available hash algorithms and exit \n");
  157     printf("  --mins=LEN   Starting length for small size bench (default: %i) \n", SMALL_SIZE_MIN_DEFAULT);
  158     printf("  --maxs=LEN   End length for small size bench (default: %i) \n", SMALL_SIZE_MAX_DEFAULT);
  159     printf("  --minl=LEN   Starting log2(length) for large size bench (default: %i) \n", LARGE_SIZELOG_MIN_DEFAULT);
  160     printf("  --maxl=LEN   End log2(length) for large size bench (default: %i) \n", LARGE_SIZELOG_MAX_DEFAULT);
  161     printf("  [hash]       Optional, bench all available hashes if not provided \n");
  162     return 0;
  163 }
  164 
  165 static int badusage(const char* exename)
  166 {
  167     printf("Bad command ... \n");
  168     help(exename);
  169     return 1;
  170 }
  171 
  172 int main(int argc, const char** argv)
  173 {
  174     const char* const exename = argv[0];
  175     int hashNb = 0;
  176     int nb_h_test = NB_HASHES;
  177     int largeTest_log_min = LARGE_SIZELOG_MIN_DEFAULT;
  178     int largeTest_log_max = LARGE_SIZELOG_MAX_DEFAULT;
  179     size_t smallTest_size_min = SMALL_SIZE_MIN_DEFAULT;
  180     size_t smallTest_size_max = SMALL_SIZE_MAX_DEFAULT;
  181 
  182     int arg_nb;
  183     for (arg_nb = 1; arg_nb < argc; arg_nb++) {
  184         const char** arg = argv + arg_nb;
  185         if (isCommand(*arg, "-h")) { assert(argc >= 1); return help(exename); }
  186         if (isCommand(*arg, "--list")) { return display_hash_names(); }
  187         if (longCommandWArg(arg, "--n=")) { nb_h_test = readIntFromChar(arg); continue; }  /* hidden command */
  188         if (longCommandWArg(arg, "--minl=")) { largeTest_log_min = readIntFromChar(arg); continue; }
  189         if (longCommandWArg(arg, "--maxl=")) { largeTest_log_max = readIntFromChar(arg); continue; }
  190         if (longCommandWArg(arg, "--mins=")) { smallTest_size_min = (size_t)readIntFromChar(arg); continue; }
  191         if (longCommandWArg(arg, "--maxs=")) { smallTest_size_max = (size_t)readIntFromChar(arg); continue; }
  192         /* not a command: must be a hash name */
  193         hashNb = hashID(*arg);
  194         if (hashNb >= 0) {
  195             nb_h_test = 1;
  196         } else {
  197             /* not a hash name: error */
  198             return badusage(exename);
  199         }
  200     }
  201 
  202     /* border case (requires (mis)using hidden command `--n=#`) */
  203     if (hashNb + nb_h_test > NB_HASHES) {
  204         printf("wrong hash selection \n");
  205         return 1;
  206     }
  207 
  208     printf(" ===  benchmarking %i hash functions  === \n", nb_h_test);
  209     if (largeTest_log_max >= largeTest_log_min) {
  210         bench_largeInput(hashCandidates+hashNb, nb_h_test, largeTest_log_min, largeTest_log_max);
  211     }
  212     if (smallTest_size_max >= smallTest_size_min) {
  213         bench_throughput_smallInputs(hashCandidates+hashNb, nb_h_test, smallTest_size_min, smallTest_size_max);
  214         bench_throughput_randomInputLength(hashCandidates+hashNb, nb_h_test, smallTest_size_min, smallTest_size_max);
  215         bench_latency_smallInputs(hashCandidates+hashNb, nb_h_test, smallTest_size_min, smallTest_size_max);
  216         bench_latency_randomInputLength(hashCandidates+hashNb, nb_h_test, smallTest_size_min, smallTest_size_max);
  217     }
  218 
  219     return 0;
  220 }