(root)/
fribidi-1.0.13/
bin/
fribidi-benchmark.c
       1  /* FriBidi
       2   * fribidi-benchmark.c - command line benchmark tool for libfribidi
       3   *
       4   * Authors:
       5   *   Behdad Esfahbod, 2001, 2002, 2004
       6   *   Dov Grobgeld, 1999, 2000
       7   *
       8   * Copyright (C) 2004 Sharif FarsiWeb, Inc
       9   * Copyright (C) 2001,2002 Behdad Esfahbod
      10   * Copyright (C) 1999,2000 Dov Grobgeld
      11   * 
      12   * This library is free software; you can redistribute it and/or
      13   * modify it under the terms of the GNU Lesser General Public
      14   * License as published by the Free Software Foundation; either
      15   * version 2.1 of the License, or (at your option) any later version.
      16   * 
      17   * This library is distributed in the hope that it will be useful,
      18   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      20   * Lesser General Public License for more details.
      21   * 
      22   * You should have received a copy of the GNU Lesser General Public License
      23   * along with this library, in a file named COPYING; if not, write to the
      24   * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      25   * Boston, MA 02110-1301, USA
      26   * 
      27   * For licensing issues, contact <fribidi.license@gmail.com>.
      28   */
      29  
      30  #include <common.h>
      31  
      32  #include <fribidi.h>
      33  #include <fribidi-deprecated.h>
      34  
      35  #include <stdio.h>
      36  
      37  #ifdef HAVE_CONFIG_H
      38  # include <config.h>
      39  #endif
      40  
      41  #ifdef STDC_HEADERS
      42  # include <stdlib.h>
      43  # include <stddef.h>
      44  #else
      45  # if HAVE_STDLIB_H
      46  #  include <stdlib.h>
      47  # endif
      48  #endif
      49  #ifdef HAVE_STRING_H
      50  # if !STDC_HEADERS && HAVE_MEMORY_H
      51  #  include <memory.h>
      52  # endif
      53  # include <string.h>
      54  #endif
      55  #ifdef HAVE_STRINGS_H
      56  # include <strings.h>
      57  #endif
      58  #ifdef HAVE_SYS_TIMES_H
      59  # include <sys/times.h>
      60  #endif
      61  #ifdef _WIN32
      62  #include <windows.h>
      63  #endif /* _WIN32 */
      64  
      65  #include "getopt.h"
      66  
      67  #define appname "fribidi_benchmark"
      68  
      69  #define MAX_STR_LEN 1000
      70  #define NUM_ITER 2000
      71  
      72  static void
      73  die2 (
      74    const char *fmt,
      75    const char *arg
      76  )
      77  {
      78    fprintf (stderr, "%s: ", appname);
      79    if (fmt)
      80      fprintf (stderr, fmt, arg);
      81    fprintf (stderr, "Try `%s --help' for more information.\n", appname);
      82    exit (-1);
      83  }
      84  
      85  #define TEST_STRING \
      86    "a THE QUICK -123,456 (FOX JUMPS ) DOG the quick !1@7#4&5^ over the dog " \
      87    "123,456 OVER THE 5%+ 4.0 LAZY"
      88  #define TEST_STRING_EXPLICIT \
      89    "this is _LJUST_o a _lsimple _Rte%ST_o th_oat  HAS A _LPDF missing" \
      90    "AnD hOw_L AbOuT, 123,987 tHiS_o a GO_oOD - _L_oTE_oST. " \
      91    "here_L is_o_o_o _R a good one_o And _r 123,987_LT_oHE_R next_o oNE:" \
      92    "_R_r and the last _LONE_o IS THE _rbest _lONE and" \
      93    "a _L_L_L_LL_L_L_L_L_L_L_L_L_Rbug_o_o_o_o_o_o" \
      94    "_R_r and the last _LONE_o IS THE _rbest _lONE and" \
      95    "A REAL BIG_l_o BUG! _L _l_r_R_L_laslaj siw_o_Rlkj sslk" \
      96    "a _L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_L_Rbug" \
      97    "here_L is_o_o_o _R ab  one_o _r 123,987_LT_oHE_R t_o oNE:" \
      98  
      99  static void
     100  help (
     101    void
     102  )
     103  {
     104    printf
     105      ("Usage: " appname " [OPTION]...\n"
     106       "A program for benchmarking the speed of the " FRIBIDI_NAME
     107       " library.\n" "\n"
     108       "  -h, --help            Display this information and exit\n"
     109       "  -V, --version         Display version information and exit\n"
     110       "  -n, --niter N         Number of iterations. Default is %d.\n"
     111       "\nReport bugs online at\n<" FRIBIDI_BUGREPORT ">.\n", NUM_ITER);
     112    exit (0);
     113  }
     114  
     115  static void
     116  version (
     117    void
     118  )
     119  {
     120    printf (appname " %s", fribidi_version_info);
     121    exit (0);
     122  }
     123  
     124  static double
     125  utime (
     126    void
     127  )
     128  {
     129  #ifdef _WIN32
     130    FILETIME creationTime, exitTime, kernelTime, userTime;
     131    HANDLE currentProcess = GetCurrentProcess();
     132    if (GetProcessTimes(currentProcess, &creationTime, &exitTime, &kernelTime, &userTime))
     133    {
     134        unsigned __int64 myTime = userTime.dwHighDateTime;
     135        myTime = (myTime << 32) | userTime.dwLowDateTime;
     136        return 1e-7 * myTime;
     137    }
     138    else
     139        return 0.0;
     140  #else /* !_WIN32 */
     141  #ifdef HAVE_SYS_TIMES_H
     142    struct tms tb;
     143    times (&tb);
     144    return 0.01 * tb.tms_utime;
     145  #else
     146  #warning Please fill in here to use other functions for determining time.
     147    return 0.0;
     148  #endif
     149  #endif
     150  }
     151  
     152  static void
     153  benchmark (
     154    const char *S_,
     155    int niter
     156  )
     157  {
     158    int len, i;
     159    FriBidiChar us[MAX_STR_LEN], out_us[MAX_STR_LEN];
     160    FriBidiStrIndex positionLtoV[MAX_STR_LEN], positionVtoL[MAX_STR_LEN];
     161    FriBidiLevel embedding_list[MAX_STR_LEN];
     162    FriBidiParType base;
     163    double time0, time1;
     164  
     165    {
     166      int j;
     167      len = strlen (S_);
     168      for (i = 0, j = 0; i < len; i++)
     169        {
     170  	if (S_[i] == '_')
     171  	  switch (S_[++i])
     172  	    {
     173  	    case '>':
     174  	      us[j++] = FRIBIDI_CHAR_LRM;
     175  	      break;
     176  	    case '<':
     177  	      us[j++] = FRIBIDI_CHAR_RLM;
     178  	      break;
     179  	    case 'l':
     180  	      us[j++] = FRIBIDI_CHAR_LRE;
     181  	      break;
     182  	    case 'r':
     183  	      us[j++] = FRIBIDI_CHAR_RLE;
     184  	      break;
     185  	    case 'L':
     186  	      us[j++] = FRIBIDI_CHAR_LRO;
     187  	      break;
     188  	    case 'R':
     189  	      us[j++] = FRIBIDI_CHAR_RLO;
     190  	      break;
     191  	    case 'o':
     192  	      us[j++] = FRIBIDI_CHAR_PDF;
     193  	      break;
     194  	    case '_':
     195  	      us[j++] = '_';
     196  	      break;
     197  	    default:
     198  	      us[j++] = '_';
     199  	      i--;
     200  	      break;
     201  	    }
     202  	else
     203  	  us[j++] = S_[i];
     204  	if (us[j] >= 'A' && us[j] <= 'F')
     205  	  us[j] += FRIBIDI_CHAR_ARABIC_ALEF - 'A';
     206  	else if (us[j] >= 'G' && us[j] <= 'Z')
     207  	  us[j] += FRIBIDI_CHAR_HEBREW_ALEF - 'G';
     208  	else if (us[j] >= '6' && us[j] <= '9')
     209  	  us[j] += FRIBIDI_CHAR_ARABIC_ZERO - '0';
     210        }
     211      len = j;
     212    }
     213  
     214    /* Start timer */
     215    time0 = utime ();
     216  
     217    for (i = 0; i < niter; i++)
     218      {
     219        /* Create a bidi string */
     220        base = FRIBIDI_PAR_ON;
     221  FRIBIDI_BEGIN_IGNORE_DEPRECATIONS
     222        if (!fribidi_log2vis (us, len, &base,
     223  			    /* output */
     224  			    out_us, positionVtoL, positionLtoV,
     225  			    embedding_list))
     226  	die2
     227  	  ("something failed in fribidi_log2vis.\n"
     228  	   "perhaps memory allocation failure.", NULL);
     229  FRIBIDI_END_IGNORE_DEPRECATIONS
     230      }
     231  
     232    /* stop timer */
     233    time1 = utime ();
     234  
     235    /* output result */
     236    printf ("Length = %d\n", len);
     237    printf ("Iterations = %d\n", niter);
     238    printf ("%d len*iterations in %f seconds\n", len * niter, time1 - time0);
     239    printf ("= %.0f kilo.length.iterations/second\n",
     240  	  1.0 * len * niter / 1000 / (time1 - time0));
     241  
     242    return;
     243  }
     244  
     245  int
     246  main (
     247    int argc,
     248    char *argv[]
     249  )
     250  {
     251    int niter = NUM_ITER;
     252  
     253    /* Parse the command line */
     254    argv[0] = appname;
     255    while (1)
     256      {
     257        int option_index = 0, c;
     258        static struct option long_options[] = {
     259  	{"help", 0, 0, 'h'},
     260  	{"version", 0, 0, 'V'},
     261  	{"niter", 0, 0, 'n'},
     262  	{0, 0, 0, 0}
     263        };
     264  
     265        c = getopt_long (argc, argv, "hVn:", long_options, &option_index);
     266        if (c == -1)
     267  	break;
     268  
     269        switch (c)
     270  	{
     271  	case 0:
     272  	  break;
     273  	case 'h':
     274  	  help ();
     275  	  break;
     276  	case 'V':
     277  	  version ();
     278  	  break;
     279  	case 'n':
     280  	  niter = atoi (optarg);
     281  	  if (niter <= 0)
     282  	    die2 ("invalid number of iterations `%s'\n", optarg);
     283  	  break;
     284  	case ':':
     285  	case '?':
     286  	  die2 (NULL, NULL);
     287  	  break;
     288  	default:
     289  	  break;
     290  	}
     291      }
     292  
     293    printf ("* Without explicit marks:\n");
     294    benchmark (TEST_STRING, niter);
     295    printf ("\n");
     296    printf ("* With explicit marks:\n");
     297    benchmark (TEST_STRING_EXPLICIT, niter);
     298  
     299    return 0;
     300  }
     301  
     302  /* Editor directions:
     303   * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent
     304   */