(root)/
glibc-2.38/
benchtests/
bench-strrchr.c
       1  /* Measure STRCHR functions.
       2     Copyright (C) 2013-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #define TEST_MAIN
      20  #ifdef WIDE
      21  # define TEST_NAME "wcsrchr"
      22  #else
      23  # define TEST_NAME "strrchr"
      24  #endif
      25  #include "bench-string.h"
      26  #include "json-lib.h"
      27  
      28  #define BIG_CHAR MAX_CHAR
      29  
      30  #ifdef WIDE
      31  # define SMALL_CHAR 1273
      32  #else
      33  # define SMALL_CHAR 127
      34  
      35  char *
      36  generic_strrchr (const char *, int);
      37  
      38  IMPL (generic_strrchr, 0)
      39  
      40  #endif
      41  
      42  typedef CHAR *(*proto_t) (const CHAR *, int);
      43  
      44  IMPL (STRRCHR, 1)
      45  
      46  static void
      47  do_one_test (json_ctx_t *json_ctx, impl_t *impl, const CHAR *s, int c,
      48  	     CHAR *exp_res)
      49  {
      50    CHAR *res = CALL (impl, s, c);
      51    size_t i, iters = INNER_LOOP_ITERS8;
      52    timing_t start, stop, cur;
      53  
      54    if (res != exp_res)
      55      {
      56        error (0, 0, "Wrong result in function %s %p %p", impl->name, res,
      57  	     exp_res);
      58        ret = 1;
      59        return;
      60      }
      61  
      62    TIMING_NOW (start);
      63    for (i = 0; i < iters; ++i)
      64      {
      65        CALL (impl, s, c);
      66      }
      67    TIMING_NOW (stop);
      68    TIMING_DIFF (cur, start, stop);
      69  
      70    json_element_double (json_ctx, (double) cur / (double) iters);
      71  }
      72  
      73  static void
      74  do_test (json_ctx_t *json_ctx, size_t align, size_t pos, size_t len,
      75  	 int seek_char, int max_char, size_t freq)
      76  /* For wcsrchr: align here means align not in bytes,
      77     but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
      78     len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
      79  {
      80    size_t i;
      81    size_t pos_chunk_sz = freq ? (pos / freq) : pos;
      82    size_t last_pos = len;
      83    CHAR *result;
      84    CHAR *buf = (CHAR *) buf1;
      85  
      86    align &= (getpagesize () - 1);
      87    if ((align + len) * sizeof (CHAR) >= page_size)
      88      return;
      89  
      90    for (i = 0; i < len; ++i)
      91      {
      92        buf[align + i] = (random () * random ()) & max_char;
      93        if (!buf[align + i])
      94  	buf[align + i] = (random () * random ()) & max_char;
      95        if (!buf[align + i])
      96  	buf[align + i] = 1;
      97        if ((i > pos || pos >= len) && buf[align + i] == seek_char)
      98  	buf[align + i] = seek_char + 10 + (random () & 15);
      99      }
     100  
     101    if (pos_chunk_sz == 0 && pos)
     102      pos_chunk_sz = 1;
     103  
     104    for (i = pos_chunk_sz; i < pos && i < len; i += pos_chunk_sz)
     105      {
     106        buf[align + i] = seek_char;
     107        last_pos = i;
     108      }
     109  
     110    buf[align + len] = 0;
     111  
     112    if (pos < len)
     113      {
     114        buf[align + pos] = seek_char;
     115        result = (CHAR *) (buf + align + pos);
     116      }
     117    else if (last_pos < len)
     118      result = (CHAR *) (buf + align + last_pos);
     119    else if (seek_char == 0)
     120      result = (CHAR *) (buf + align + len);
     121    else
     122      result = NULL;
     123  
     124    json_element_object_begin (json_ctx);
     125    json_attr_uint (json_ctx, "len", len);
     126    json_attr_uint (json_ctx, "pos", pos);
     127    json_attr_uint (json_ctx, "align", align);
     128    json_attr_uint (json_ctx, "freq", freq);
     129    json_attr_uint (json_ctx, "seek", seek_char);
     130    json_attr_uint (json_ctx, "max_char", max_char);
     131    json_array_begin (json_ctx, "timings");
     132  
     133    FOR_EACH_IMPL (impl, 0)
     134      do_one_test (json_ctx, impl, (CHAR *) (buf + align), seek_char, result);
     135  
     136    json_array_end (json_ctx);
     137    json_element_object_end (json_ctx);
     138  }
     139  
     140  int
     141  test_main (void)
     142  {
     143    json_ctx_t json_ctx;
     144    size_t i, j, k;
     145    int seek;
     146  
     147    test_init ();
     148    json_init (&json_ctx, 0, stdout);
     149  
     150    json_document_begin (&json_ctx);
     151    json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
     152  
     153    json_attr_object_begin (&json_ctx, "functions");
     154    json_attr_object_begin (&json_ctx, TEST_NAME);
     155    json_attr_string (&json_ctx, "bench-variant", "");
     156  
     157    json_array_begin (&json_ctx, "ifuncs");
     158    FOR_EACH_IMPL (impl, 0)
     159      json_element_string (&json_ctx, impl->name);
     160    json_array_end (&json_ctx);
     161  
     162    json_array_begin (&json_ctx, "results");
     163  
     164    for (seek = 0; seek <= 23; seek += 23)
     165      {
     166        for (j = 1; j <= 256; j = (j * 4))
     167  	{
     168  	  for (i = 1; i < 9; ++i)
     169  	    {
     170  	      do_test (&json_ctx, 0, 16 << i, 2048, seek, SMALL_CHAR, j);
     171  	      do_test (&json_ctx, i, 16 << i, 2048, seek, SMALL_CHAR, j);
     172  	    }
     173  
     174  	  for (i = 1; i < 8; ++i)
     175  	    {
     176  	      do_test (&json_ctx, i, 64, 256, seek, SMALL_CHAR, j);
     177  	      do_test (&json_ctx, i, 64, 256, seek, BIG_CHAR, j);
     178  
     179  	      do_test (&json_ctx, i * 15, 64, 256, seek, SMALL_CHAR, j);
     180  	      do_test (&json_ctx, i * 15, 64, 256, seek, BIG_CHAR, j);
     181  	    }
     182  
     183  	  for (i = 0; i < 32; ++i)
     184  	    {
     185  	      do_test (&json_ctx, 0, i, i + 1, seek, SMALL_CHAR, j);
     186  	      do_test (&json_ctx, 0, i, i + 1, seek, BIG_CHAR, j);
     187  	      do_test (&json_ctx, getpagesize () - i / 2 - 1, i, i + 1, seek,
     188  		       SMALL_CHAR, j);
     189  	    }
     190  
     191  	  for (i = (16 / sizeof (CHAR)); i <= (288 / sizeof (CHAR)); i += 32)
     192  	    {
     193  	      do_test (&json_ctx, 0, i - 16, i, seek, SMALL_CHAR, j);
     194  	      do_test (&json_ctx, 0, i, i + 16, seek, SMALL_CHAR, j);
     195  	    }
     196  
     197  	  for (i = (16 / sizeof (CHAR)); i <= (2048 / sizeof (CHAR)); i += i)
     198  	    {
     199  	      for (k = 0; k <= (288 / sizeof (CHAR));
     200  		   k += (48 / sizeof (CHAR)))
     201  		{
     202  		  do_test (&json_ctx, 0, k, i, seek, SMALL_CHAR, j);
     203  		  do_test (&json_ctx, 0, i, i + k, seek, SMALL_CHAR, j);
     204  
     205  		  if (k < i)
     206  		    {
     207  		      do_test (&json_ctx, 0, i - k, i, seek, SMALL_CHAR, j);
     208  		      do_test (&json_ctx, 0, k, i - k, seek, SMALL_CHAR, j);
     209  		      do_test (&json_ctx, 0, i, i - k, seek, SMALL_CHAR, j);
     210  		    }
     211  		}
     212  	    }
     213  
     214  	  if (seek == 0)
     215  	    {
     216  	      break;
     217  	    }
     218  	}
     219      }
     220  
     221    json_array_end (&json_ctx);
     222    json_attr_object_end (&json_ctx);
     223    json_attr_object_end (&json_ctx);
     224    json_document_end (&json_ctx);
     225  
     226    return ret;
     227  }
     228  
     229  #include <support/test-driver.c>
     230  
     231  #define weak_alias(X,Y)
     232  #define libc_hidden_builtin_def(X)
     233  #ifndef WIDE
     234  # undef STRRCHR
     235  # define STRRCHR generic_strrchr
     236  # define __memrchr memrchr
     237  # include <string/strrchr.c>
     238  #endif