aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/include/eina_benchmark.h
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/eina/src/include/eina_benchmark.h
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/eina/src/include/eina_benchmark.h')
-rw-r--r--libraries/eina/src/include/eina_benchmark.h453
1 files changed, 453 insertions, 0 deletions
diff --git a/libraries/eina/src/include/eina_benchmark.h b/libraries/eina/src/include/eina_benchmark.h
new file mode 100644
index 0000000..721e1c0
--- /dev/null
+++ b/libraries/eina/src/include/eina_benchmark.h
@@ -0,0 +1,453 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef EINA_BENCHMARK_H_
20#define EINA_BENCHMARK_H_
21
22#include "eina_array.h"
23
24
25
26/**
27 * @page tutorial_benchmark_page Benchmark Tutorial
28 *
29 * The Benchmark module allows you to write easily benchmarks
30 * framework in a project for timing critical part and detect slow
31 * parts of code. In addition it automatically creates data files of
32 * these benchmark, as well as a gnuplot file which can display the
33 * comparison curves of the benchmarks.
34 *
35 * @section tutorial_benchmark_basic_usage Basic Usage
36 *
37 * To create a basic benchmark, you have to follow these steps:
38 *
39 * @li Create a new bechmark
40 * @li Write the functions that wraps the the functions you want to
41 * bechmark.
42 * @li Register these wrappers functions.
43 * @li Run the benchmark.
44 * @li Free the memory.
45 *
46 * Here is a basic example of bechmark which creates two functions
47 * that will be run. These functions just print a message.
48 *
49 * @code
50 * #include <stdlib.h>
51 * #include <stdio.h>
52 *
53 * #include <Eina.h>
54 *
55 * static
56 * void work1(int request)
57 * {
58 * printf ("work1 in progress... Request: %d\n", request);
59 * }
60 *
61 * static
62 * void work2(int request)
63 * {
64 * printf ("work2 in progress... Request: %d\n", request);
65 * }
66 *
67 * int main()
68 * {
69 * Eina_Benchmark *test;
70 * Eina_Array *ea;
71 *
72 * if (!eina_init())
73 * return EXIT_FAILURE;
74 *
75 * test = eina_benchmark_new("test", "run");
76 * if (!test)
77 * goto shutdown_eina;
78 *
79 * eina_benchmark_register(test, "work-1", EINA_BENCHMARK(work1), 200, 300, 10);
80 * eina_benchmark_register(test, "work-2", EINA_BENCHMARK(work2), 100, 150, 5);
81 *
82 * ea = eina_benchmark_run(test);
83 *
84 * eina_benchmark_free(test);
85 * eina_shutdown();
86 *
87 * return EXIT_SUCCESS;
88 *
89 * shutdown_eina:
90 * eina_shutdown();
91 *
92 * return EXIT_FAILURE;
93 * }
94 * @endcode
95 *
96 * As "test", "run" are passed to eina_benchmark_new() and as the tests
97 * "work-1" and "work-2" are registered, the data files
98 * bench_test_run.work-1.data and bench_test_run.work-2.data will be
99 * created after the eina_benchmark_run() call. They contain four
100 * columns. The file bench_test_run.work-1.data contains for example:
101 *
102 * @code
103 * # specimen experiment time starting time ending time
104 * 200 23632 2852446 2876078
105 * 210 6924 2883046 2889970
106 * 220 6467 2895962 2902429
107 * 230 6508 2908271 2914779
108 * 240 6278 2920610 2926888
109 * 250 6342 2932830 2939172
110 * 260 6252 2944954 2951206
111 * 270 6463 2956978 2963441
112 * 280 6347 2969548 2975895
113 * 290 6457 2981702 2988159
114 * @endcode
115 *
116 * The first column (specimen) is the integer passed to the work1()
117 * function when the test is run. The second column (experiment time)
118 * is the time, in nanosecond, that work1() takes. The third and
119 * fourth columnd are self-explicit.
120 *
121 * You can see that the integer passed work1() starts from 200 and
122 * finishes at 290, with a step of 10. These values are computed withe
123 * last 3 values passed to eina_benchmark_register(). See the document
124 * of that function for the detailed behavior.
125 *
126 * The gnuplot file will be named bench_test_run.gnuplot. Just run:
127 *
128 * @code
129 * gnuplot bench_test_run.gnuplot
130 * @endcode
131 *
132 * to create the graphic of the comparison curves. The image file is
133 * named output_test_run.png.
134 *
135 * @section tutorial_benchmark_advanced_usage More Advanced Usage
136 *
137 * In this section, several test will be created and run. The idea is
138 * exactly the same than in the previous section, but with some basic
139 * automatic way to run all the benchmarks. The following code
140 * benchmarks some Eina converts functions, and some Eina containers
141 * types:
142 *
143 * @code
144 * #include <stdlib.h>
145 * #include <stdio.h>
146 * #include <time.h>
147 *
148 * #include <Eina.h>
149 *
150 * static void bench_convert(Eina_Benchmark *bench);
151 * static void bench_container(Eina_Benchmark *bench);
152 *
153 * typedef struct _Benchmark_Case Benchmark_Case;
154 *
155 * struct _Benchmark_Case
156 * {
157 * const char *bench_case;
158 * void (*build)(Eina_Benchmark *bench);
159 * };
160 *
161 * static const Benchmark_Case benchmarks[] = {
162 * { "Bench 1", bench_convert },
163 * { "Bench 2", bench_container },
164 * { NULL, NULL }
165 * };
166 *
167 * static
168 * void convert1(int request)
169 * {
170 * char tmp[128];
171 * int i;
172 *
173 * srand(time(NULL));
174 *
175 * for (i = 0; i < request; ++i)
176 * eina_convert_itoa(rand(), tmp);
177 * }
178 *
179 * static
180 * void convert2(int request)
181 * {
182 * char tmp[128];
183 * int i;
184 *
185 * srand(time(NULL));
186 *
187 * for (i = 0; i < request; ++i)
188 * eina_convert_xtoa(rand(), tmp);
189 * }
190 *
191 * static void
192 * bench_convert(Eina_Benchmark *bench)
193 * {
194 * eina_benchmark_register(bench, "convert-1", EINA_BENCHMARK(convert1), 200, 400, 10);
195 * eina_benchmark_register(bench, "convert-2", EINA_BENCHMARK(convert2), 200, 400, 10);
196 * }
197 *
198 * static
199 * void array(int request)
200 * {
201 * Eina_Array *array;
202 * Eina_Array_Iterator it;
203 * int *data;
204 * int i;
205 *
206 * srand(time(NULL));
207 *
208 * array = eina_array_new(64);
209 *
210 * for (i = 0; i < request; ++i)
211 * {
212 * data = (int *)malloc(sizeof(int));
213 * if (!data) continue;
214 * *data = rand();
215 * eina_array_push(array, data);
216 * }
217 *
218 * EINA_ARRAY_ITER_NEXT(array, i, data, it)
219 * free(data);
220 *
221 * eina_array_free(array);
222 * }
223 *
224 * static
225 * void list(int request)
226 * {
227 * Eina_List *l = NULL;
228 * int *data;
229 * int i;
230 *
231 * srand(time(NULL));
232 *
233 * for (i = 0; i < request; ++i)
234 * {
235 * data = (int *)malloc(sizeof(int));
236 * if (!data) continue;
237 * *data = rand();
238 * l = eina_list_prepend(l, data);
239 * }
240 *
241 * while (l)
242 * {
243 * free(eina_list_data_get(l));
244 * l = eina_list_remove_list(l, l);
245 * }
246 * }
247 *
248 * static void
249 * bench_container(Eina_Benchmark *bench)
250 * {
251 * eina_benchmark_register(bench, "array", EINA_BENCHMARK(array), 200, 300, 10);
252 * eina_benchmark_register(bench, "list", EINA_BENCHMARK(list), 200, 300, 10);
253 * }
254 *
255 * int main()
256 * {
257 * Eina_Benchmark *test;
258 * Eina_Array *ea;
259 * unsigned int i;
260 *
261 * if (!eina_init())
262 * return EXIT_FAILURE;
263 *
264 * for (i = 0; benchmarks[i].bench_case != NULL; ++i)
265 * {
266 * test = eina_benchmark_new(benchmarks[i].bench_case, "Benchmark example");
267 * if (!test)
268 * continue;
269 *
270 * benchmarks[i].build(test);
271 *
272 * ea = eina_benchmark_run(test);
273 *
274 * eina_benchmark_free(test);
275 * }
276 *
277 * eina_shutdown();
278 *
279 * return EXIT_SUCCESS;
280 * }
281 * @endcode
282 *
283 * gnuplot can be used to see how are performed the convert functions
284 * together, as well as how are performed the containers. So it is now
285 * easy to see that the hexadecimal convert function is faster than
286 * the decimal one, and that arrays are faster than lists.
287 *
288 * You can improve all that by executing automatically gnuplot in your
289 * program, or integrate the Eina benchmark framework in an autotooled
290 * project. See that
291 * <a href="http://trac.enlightenment.org/e/wiki/AutotoolsIntegration#Benchmark">page</a>
292 * for more informations.
293 *
294 */
295
296
297/**
298 * @addtogroup Eina_Benchmark_Group Benchmark
299 *
300 * These functions allow you to add benchmark framework in a project
301 * for timing critical part and detect slow parts of code. It is used
302 * in Eina to compare the time used by eina, glib, evas and ecore data
303 * types.
304 *
305 * To use the benchmark module, Eina must be initialized with
306 * eina_init() and later shut down with eina_shutdown(). A benchmark
307 * is created with eina_benchmark_new() and freed with
308 * eina_benchmark_free().
309 *
310 * eina_benchmark_register() adds a test to a benchmark. That test can
311 * be run a certain amount of times. Adding more than one test to be
312 * executed allows the comparison between several parts of a program,
313 * or different implementations.
314 *
315 * eina_benchmark_run() runs all the tests registered with
316 * eina_benchmark_register(). The amount of time of each test is
317 * written in a gnuplot file.
318 *
319 * For more information, you can look at the @ref tutorial_benchmark_page.
320 */
321
322/**
323 * @addtogroup Eina_Tools_Group Tools
324 *
325 * @{
326 */
327
328/**
329 * @defgroup Eina_Benchmark_Group Benchmark
330 *
331 * @{
332 */
333
334/**
335 * @typedef Eina_Benchmark
336 * Type for a benchmark.
337 */
338typedef struct _Eina_Benchmark Eina_Benchmark;
339
340/**
341 * @typedef Eina_Benchmark_Specimens
342 * Type for a test function to be called when running a benchmark.
343 */
344typedef void (*Eina_Benchmark_Specimens)(int request);
345
346/**
347 * @def EINA_BENCHMARK
348 * @brief cast to an #Eina_Benchmark_Specimens.
349 *
350 * @param function The function to cast.
351 *
352 * This macro casts @p function to Eina_Benchmark_Specimens.
353 */
354#define EINA_BENCHMARK(function) ((Eina_Benchmark_Specimens)function)
355
356
357/**
358 * @brief Create a new array.
359 *
360 * @param name The name of the benchmark.
361 * @param run The name of the run.
362 * @return @c NULL on failure, non @c NULL otherwise.
363 *
364 * This function creates a new benchmark. @p name and @p run are used
365 * to name the gnuplot file that eina_benchmark_run() will create.
366 *
367 * This function return a valid benchmark on success, or @c NULL if
368 * memory allocation fails. In that case, the error is set to
369 * #EINA_ERROR_OUT_OF_MEMORY.
370 *
371 * When the new module is not needed anymore, use
372 * eina_benchmark_free() to free the allocated memory.
373 */
374EAPI Eina_Benchmark *eina_benchmark_new(const char *name,
375 const char *run);
376
377/**
378 * @brief Free a benchmark object.
379 *
380 * @param bench The benchmark to free.
381 *
382 * This function removes all the benchmark tests that have been
383 * registered and frees @p bench. If @p bench is @c NULL, this
384 * function returns immediately.
385 */
386EAPI void eina_benchmark_free(Eina_Benchmark *bench);
387
388/**
389 * @brief Add a test to a benchmark.
390 *
391 * @param bench The benchmark.
392 * @param name The name of the test.
393 * @param bench_cb The test function to be called.
394 * @param count_start The start data to be passed to @p bench_cb.
395 * @param count_end The end data to be passed to @p bench_cb.
396 * @param count_step The step data to be passed to @p bench_cb.
397 * @return #EINA_FALSE on failure, #EINA_TRUE otherwise.
398 *
399 * This function adds the test named @p name to @p benchmark. @p
400 * bench_cb is the function called when the test is executed. That
401 * test can be executed a certain amount of time. @p start, @p end and
402 * @p step define a loop with a step increment. The integer that is
403 * increasing by @p step from @p start to @p end is passed to @p
404 * bench_cb when eina_benchmark_run() is called.
405 *
406 * If @p bench is @c NULL, this function returns imediatly. If the
407 * allocation of the memory of the test to add fails, the error is set
408 * to #EINA_ERROR_OUT_OF_MEMORY. This function returns #EINA_FALSE
409 * on failure, #EINA_TRUE otherwise.
410 */
411EAPI Eina_Bool eina_benchmark_register(Eina_Benchmark *bench,
412 const char *name,
413 Eina_Benchmark_Specimens bench_cb,
414 int count_start,
415 int count_end,
416 int count_set);
417
418/**
419 * @brief Run the benchmark tests that have been registered.
420 *
421 * @param bench The benchmark.
422 * @return The list of names of the test files.
423 *
424 * This function runs all the tests that as been registered with
425 * eina_benchmark_register() and save the result in a gnuplot
426 * file. The name of the file has the following format:
427 *
428 * @code
429 * bench_[name]_[run]%s.gnuplot
430 * @endcode
431 *
432 * where [name] and [run] are the values passed to
433 * eina_benchmark_new().
434 *
435 * Each registered test is executed and timed. The time is written to
436 * the gnuplot file. The number of times each test is executed is
437 * controlled by the parameters passed to eina_benchmark_register().
438 *
439 * If @p bench is @c NULL, this functions returns @c NULL
440 * immediately. Otherwise, it returns the list of the names of each
441 * test.
442 */
443EAPI Eina_Array *eina_benchmark_run(Eina_Benchmark *bench);
444
445/**
446 * @}
447 */
448
449/**
450 * @}
451 */
452
453#endif /* EINA_BENCHMARK_H_ */