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
72static void
73die2 (
74 const char *fmt,
75 const char *arg
76)
77{
78 fprintf (stderr, format: "%s: ", appname);
79 if (fmt)
80 fprintf (stderr, format: fmt, arg);
81 fprintf (stderr, format: "Try `%s --help' for more information.\n", appname);
82 exit (status: -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
99static void
100help (
101 void
102)
103{
104 printf
105 (format: "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 (status: 0);
113}
114
115static void
116version (
117 void
118)
119{
120 printf (appname " %s", fribidi_version_info);
121 exit (status: 0);
122}
123
124static double
125utime (
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 (buffer: &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
152static void
153benchmark (
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: 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;
221FRIBIDI_BEGIN_IGNORE_DEPRECATIONS
222 if (!fribidi_log2vis (str: us, len, pbase_dir: &base,
223 /* output */
224 visual_str: out_us, positions_L_to_V: positionVtoL, positions_V_to_L: positionLtoV,
225 embedding_levels: embedding_list))
226 die2
227 (fmt: "something failed in fribidi_log2vis.\n"
228 "perhaps memory allocation failure.", NULL);
229FRIBIDI_END_IGNORE_DEPRECATIONS
230 }
231
232 /* stop timer */
233 time1 = utime ();
234
235 /* output result */
236 printf (format: "Length = %d\n", len);
237 printf (format: "Iterations = %d\n", niter);
238 printf (format: "%d len*iterations in %f seconds\n", len * niter, time1 - time0);
239 printf (format: "= %.0f kilo.length.iterations/second\n",
240 1.0 * len * niter / 1000 / (time1 - time0));
241
242 return;
243}
244
245int
246main (
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: argc, argv: argv, shortopts: "hVn:", longopts: long_options, longind: &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 (nptr: optarg);
281 if (niter <= 0)
282 die2 (fmt: "invalid number of iterations `%s'\n", arg: optarg);
283 break;
284 case ':':
285 case '?':
286 die2 (NULL, NULL);
287 break;
288 default:
289 break;
290 }
291 }
292
293 printf (format: "* Without explicit marks:\n");
294 benchmark (TEST_STRING, niter);
295 printf (format: "\n");
296 printf (format: "* 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 */
305

source code of gtk/subprojects/fribidi/bin/fribidi-benchmark.c