LCOV - code coverage report
Current view: top level - src/bindings/intercept/env/benchmarks - benchmark_getenv.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 115 0.0 %
Date: 2022-05-21 16:19:22 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief benchmark for getenv
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : #include <kdbtimer.hpp>
      11             : #include <keyset.hpp>
      12             : 
      13             : #include <fstream>
      14             : #include <iostream>
      15             : #include <unistd.h>
      16             : 
      17             : #include <dlfcn.h>
      18             : #include <string.h>
      19             : extern "C" char ** environ;
      20             : 
      21             : 
      22             : const long long nr_keys = 30;
      23             : 
      24             : // long long iterations = 100000000000LL; // elitebenchmark lookup
      25             : long long iterations = 1000000LL; // elitebenchmark
      26             : // long long iterations = 100LL; // valgrind
      27             : 
      28             : // not needed in benchmarks:
      29           0 : long long iterations1 = iterations / 100;
      30             : 
      31             : const int benchmarkIterations = 11; // is a good number to not need mean values for median
      32             : 
      33           0 : const std::string filename = "check.txt";
      34             : 
      35           0 : const std::string csvfilename = "data.csv";
      36             : 
      37           0 : std::ofstream dump (filename);
      38           0 : std::ofstream data (csvfilename);
      39             : 
      40             : 
      41             : // from libgetenv
      42             : namespace ckdb
      43             : {
      44             : char * elektraBootstrapGetEnv (const char * name);
      45             : }
      46             : 
      47             : 
      48             : // very fast benchmarks without any if:
      49             : 
      50           0 : __attribute__ ((noinline)) void benchmark_nothing ()
      51             : {
      52           0 :         static Timer t ("nothing");
      53             : 
      54           0 :         t.start ();
      55           0 :         t.stop ();
      56           0 :         std::cout << t;
      57           0 :         dump << t.name << std::endl;
      58           0 : }
      59             : 
      60           0 : __attribute__ ((noinline)) void benchmark_getenv ()
      61             : {
      62           0 :         static Timer t ("elektra getenv");
      63             : 
      64           0 :         t.start ();
      65           0 :         for (long long i = 0; i < iterations; ++i)
      66             :         {
      67           0 :                 getenv ("HELLO");
      68           0 :                 __asm__("");
      69             :         }
      70           0 :         t.stop ();
      71           0 :         std::cout << t;
      72           0 :         dump << t.name << std::endl;
      73           0 : }
      74             : 
      75           0 : __attribute__ ((noinline)) void benchmark_dl_next_getenv ()
      76             : {
      77           0 :         static Timer t ("dl next getenv");
      78           0 :         typedef char * (*gfcn) (const char *);
      79           0 :         union Sym
      80             :         {
      81             :                 void * d;
      82             :                 gfcn f;
      83             :         } sym;
      84           0 :         sym.d = dlsym (RTLD_NEXT, "getenv");
      85           0 :         gfcn dl_libc_getenv = sym.f;
      86             : 
      87           0 :         t.start ();
      88           0 :         for (long long i = 0; i < iterations; ++i)
      89             :         {
      90           0 :                 dl_libc_getenv ("HELLO");
      91           0 :                 __asm__("");
      92             :         }
      93           0 :         t.stop ();
      94           0 :         std::cout << t;
      95           0 :         dump << t.name << std::endl;
      96           0 : }
      97             : 
      98             : 
      99           0 : __attribute__ ((noinline)) void benchmark_libc_getenv ()
     100             : {
     101           0 :         typedef char * (*gfcn) (const char *);
     102           0 :         union Sym
     103             :         {
     104             :                 void * d;
     105             :                 gfcn f;
     106             :         } sym;
     107             : 
     108           0 :         void * handle = dlopen ("/lib/x86_64-linux-gnu/libc-2.19.so", RTLD_NOW);
     109           0 :         if (!handle)
     110             :         {
     111           0 :                 handle = dlopen ("/lib/i386-linux-gnu/libc-2.19.so", RTLD_NOW);
     112             :         }
     113           0 :         if (!handle)
     114             :         {
     115           0 :                 std::cout << "Aborting, could not find libc" << std::endl;
     116           0 :                 return;
     117             :         }
     118             : 
     119           0 :         static Timer t ("libc getenv");
     120           0 :         sym.d = dlsym (handle, "getenv");
     121           0 :         gfcn dl_libc_getenv = sym.f;
     122             : 
     123           0 :         t.start ();
     124           0 :         for (long long i = 0; i < iterations; ++i)
     125             :         {
     126           0 :                 dl_libc_getenv ("HELLO");
     127           0 :                 __asm__("");
     128             :         }
     129           0 :         t.stop ();
     130           0 :         std::cout << t;
     131           0 :         dump << t.name << std::endl;
     132             : }
     133             : 
     134             : 
     135           0 : __attribute__ ((noinline)) void benchmark_bootstrap_getenv ()
     136             : {
     137           0 :         static Timer t ("bootstrap getenv");
     138           0 :         t.start ();
     139           0 :         for (long long i = 0; i < iterations; ++i)
     140             :         {
     141           0 :                 ckdb::elektraBootstrapGetEnv ("HELLO");
     142           0 :                 __asm__("");
     143             :         }
     144           0 :         t.stop ();
     145           0 :         std::cout << t;
     146           0 :         dump << t.name << std::endl;
     147           0 : }
     148             : 
     149           0 : __attribute__ ((noinline)) void benchmark_kslookup ()
     150             : {
     151           0 :         static Timer t ("kslookup");
     152           0 :         using namespace kdb; // needed for KS_END
     153           0 :         kdb::KeySet ks (100,
     154             :                         /*
     155             :                          *kdb::Key("user:/env/override/some", KEY_END),
     156             :                          *kdb::Key("user:/env/override/a/key", KEY_END),
     157             :                          *kdb::Key("user:/env/override/b/key", KEY_END),
     158             :                          *kdb::Key("user:/env/override/c/key", KEY_END),
     159             :                          *kdb::Key("user:/env/override/d/key", KEY_END),
     160             :                          */
     161           0 :                         KS_END);
     162           0 :         for (int i = 0; i < nr_keys; ++i)
     163             :         {
     164           0 :                 char x[100];
     165           0 :                 sprintf (x, "user:/env/override/hello%d_%d", i, i);
     166           0 :                 ks.append (*kdb::Key (x, KEY_END));
     167             :         }
     168           0 :         Key lookupKey ("user:/env/override/HELLO", KEY_END);
     169           0 :         t.start ();
     170           0 :         for (long long i = 0; i < iterations; ++i)
     171             :         {
     172           0 :                 ks.lookup (lookupKey);
     173           0 :                 __asm__("");
     174             :         }
     175           0 :         t.stop ();
     176           0 :         std::cout << t;
     177           0 : }
     178             : 
     179           0 : void computer_info ()
     180             : {
     181           0 :         std::cout << std::endl;
     182           0 :         std::cout << std::endl;
     183             : #ifndef _WIN32
     184           0 :         char hostname[1024];
     185           0 :         gethostname (hostname, 1023);
     186           0 :         std::cout << "hostname " << hostname << std::endl;
     187             : #endif
     188             : #ifdef __GNUC__
     189           0 :         std::cout << "gcc: " << __GNUC__ << std::endl;
     190             : #endif
     191             : #ifdef __INTEL_COMPILER
     192             :         std::cout << "icc: " << __INTEL_COMPILER << std::endl;
     193             : #endif
     194             : #ifdef __clang__
     195             :         std::cout << "clang: " << __clang__ << std::endl;
     196             : #endif
     197           0 :         std::cout << "sizeof(int) " << sizeof (int) << std::endl;
     198           0 :         std::cout << "sizeof(long) " << sizeof (long) << std::endl;
     199           0 :         std::cout << "sizeof(long long) " << sizeof (long long) << std::endl;
     200           0 :         std::cout << "iterations " << iterations << std::endl;
     201           0 :         std::cout << "filename " << filename << std::endl;
     202           0 :         std::cout << std::endl;
     203           0 : }
     204             : 
     205           0 : int main (int argc, char ** argv)
     206             : {
     207           0 :         computer_info ();
     208             : 
     209           0 :         clearenv ();
     210           0 :         for (int i = 0; i < nr_keys; ++i)
     211             :         {
     212           0 :                 char x[100];
     213           0 :                 sprintf (x, "hello%d_%d", i, i);
     214           0 :                 setenv (x, x, 0);
     215             :         }
     216             : 
     217           0 :         if (argc == 2)
     218             :         {
     219           0 :                 iterations = atoll (argv[1]);
     220           0 :                 iterations1 = iterations / 100;
     221             :         }
     222             : 
     223           0 :         for (int i = 0; i < benchmarkIterations; ++i)
     224             :         {
     225           0 :                 std::cout << i << std::endl;
     226             : 
     227           0 :                 benchmark_nothing ();
     228           0 :                 benchmark_getenv ();
     229           0 :                 benchmark_libc_getenv ();
     230           0 :                 benchmark_bootstrap_getenv ();
     231             : 
     232           0 :                 benchmark_kslookup ();
     233             : 
     234             :                 // benchmark_hashmap();
     235             :                 // benchmark_hashmap_find();
     236             :         }
     237             : 
     238           0 :         data << "value,benchmark" << std::endl;
     239           0 : }

Generated by: LCOV version 1.13