]> Creatis software - gdcm.git/blob - TestInline.cxx
e7fcfeeb1513868edbcda3875a79fdb158544bbd
[gdcm.git] / TestInline.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: TestInline.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/09/28 07:35:49 $
7   Version:   $Revision: 1.15 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 // This test is expected to 'show' the actual effect on an 'inline' function.
19 // We exchange 2 numbers
20 // - with a macro : this is the quicker (any doubt ?)
21 // - with a function, passing the params by pointer
22 // - with a function, passing the params by reference (exactly same time)
23 // - with an inline function described in the .cxx
24 //                                                   absolutely NO effect ?!?
25 // - with a function, described in the .h
26 //                                                   absolutely NO effect ?!?
27 // - with an inline function, described in the .h
28 //                                                   absolutely NO effect ?!?
29 //
30 // Which CXX_FLAGS, LINKER_FLAGS, ...,  must we set to see the difference?
31
32 #include "gdcmUtil.h"
33
34 #ifdef _MSC_VER
35 #include <time.h>
36 #define GET_TIME(a) a=clock()
37 #define HOW_LONG(b,a)                             \
38    std::cout  << (double) (b-a)  << std::endl  
39 #else
40 #include <sys/times.h>
41 #define GET_TIME(a)  times(&a)
42 #define HOW_LONG(b,a)                             \
43    std::cout                                      \
44         << (long) ((b.tms_utime) - (a.tms_utime)) \
45         << std::endl  
46 #endif
47
48 #include <iostream>
49
50 void        frswap (double &a, double &b);
51 void        fpswap (double *a, double *b);
52 inline void ifrswap(double &a, double &b);
53 inline void ifpswap(double *a, double *b);
54
55 uint8_t     passDirect8(uint8_t a,  uint8_t b);
56 uint8_t     passRef8(uint8_t &a, uint8_t &b);
57 uint8_t     passPtr8(uint8_t *a, uint8_t *b);
58
59 uint16_t     passDirect16(uint16_t a,  uint16_t b);
60 uint16_t     passRef16(uint16_t &a, uint16_t &b);
61 uint16_t     passPtr16(uint16_t *a, uint16_t *b);
62
63 uint32_t     passDirect32(uint32_t a,  uint32_t b);
64 uint32_t     passRef32(uint32_t &a, uint32_t &b);
65 uint32_t     passPtr32(uint32_t *a, uint32_t *b);
66
67 double     passDirect(double a,  double b);
68 double     passRef(double &a, double &b);
69 double     passPtr(double *a, double *b);
70
71 #define           \
72 mswap(a, b)       \
73 {                 \
74    double tmp = a;\
75    a   = b;       \
76    b   = tmp;     \
77 }
78
79 //  ============= no inline
80
81 void frswap(double &a, double &b)
82 {
83    double tmp;
84    tmp = a;
85    a   = b;
86    b   = tmp;
87 }
88
89 void fpswap(double *a, double *b)
90 {
91    double tmp;
92    tmp = *a;
93    *a  = *b;
94    *b  = tmp;
95 }
96
97 //  ============= inline
98
99 inline void ifpswap(double *a, double *b)
100 {
101    double tmp;
102    tmp = *a;
103    *a  = *b;
104    *b  = tmp;
105 }
106
107 inline void ifrswap(double &a, double &b)
108 {
109    double tmp;
110    tmp = a;
111    a   = b;
112    b   = tmp;
113 }
114
115
116 uint32_t passRef32(uint32_t &a, uint32_t &b)
117 {
118    return a + b;
119
120 uint32_t passPtr32(uint32_t *a, uint32_t *b)
121 {
122    return *a + *b;
123
124 uint32_t passDirect32(uint32_t a, uint32_t b)
125 {
126    return a + b;
127
128
129
130 uint16_t passRef16(uint16_t &a, uint16_t &b)
131 {
132    return a + b;
133
134 uint16_t passPtr16(uint16_t *a, uint16_t *b)
135 {
136    return *a + *b;
137
138 uint16_t passDirect16(uint16_t a, uint16_t b)
139 {
140    return a + b;
141
142
143 uint8_t passRef8(uint8_t &a, uint8_t &b)
144 {
145    return a + b;
146
147 uint8_t passPtr8(uint8_t *a, uint8_t *b)
148 {
149    return *a + *b;
150
151 uint8_t passDirect8(uint8_t a, uint8_t b)
152 {
153    return a + b;
154
155
156 float passRefFloat(float &a, float &b)
157 {
158    return a + b;
159
160 float passPtrFloat(float *a, float *b)
161 {
162    return *a + *b;
163
164 float passDirectFloat(float a, float b)
165 {
166    return a + b;
167
168
169 double passRefDouble(double &a, double &b)
170 {
171    return a + b;
172
173 double passPtrDouble(double *a, double *b)
174 {
175    return *a + *b;
176
177 double passDirectDouble(double a, double b)
178 {
179    return a + b;
180
181
182 int TestInline(int argc, char *argv[])
183 {
184
185 #ifdef _MSC_VER
186    clock_t tms1, tms2;
187 #else
188    struct tms tms1, tms2;
189 #endif
190
191 // ====================================================================
192
193    std::cout << std::endl << std::endl
194              << "Just to be sure : sizes of native types" << std::endl
195              << "======================================="      
196              << std::endl << std::endl;
197    // just to know, on every proc
198    std::cout << "Size of char      " << sizeof(char)      << std::endl;   
199    std::cout << "Size of short int " << sizeof(short int) << std::endl;
200    std::cout << "Size of int       " << sizeof(int)       << std::endl;
201    std::cout << "Size of long      " << sizeof(long)      << std::endl;
202    std::cout << "Size of float     " << sizeof(float)     << std::endl;
203    std::cout << "Size of double    " << sizeof(double)    << std::endl;
204    std::cout << std::endl;
205    std::cout << "Size of char*     " << sizeof(char*)     << std::endl;
206    std::cout << "Size of short int*" << sizeof(short int*)<< std::endl;
207    std::cout << "Size of int*      " << sizeof(int*)      << std::endl;
208    std::cout << "Size of double*   " << sizeof(double*)   << std::endl;
209    std::cout <<  "-----------------" << std::endl;   
210    
211  // ====================================================================
212     
213    unsigned int nbLoop; 
214    unsigned int i;
215       
216    if (argc > 1)
217       nbLoop = atoi(argv[1]);
218    else
219       nbLoop = 100000000;
220
221    uint8_t  x8 =1, y8 =2;    
222    uint16_t x16=1, y16=2;    
223    uint32_t x32=1, y32=2;    
224    float  fx =1.0f, fy=1.0f;
225    double dx =1.0 , dy=1.0;
226    double a = 1, b = 2;
227    
228  // ====================================================================
229  
230    std::cout << std::endl << std::endl
231              << "Check different ways of passing scalars to a function "<< nbLoop << " times"  << std::endl
232              << "=====================================================" 
233              << std::endl << std::endl; 
234     
235    std::cout << "Pass uint_8 param directly"
236              << std::endl;
237
238    GET_TIME(tms1);    
239    for(i = 0 ; i< nbLoop ; i++)
240    {
241       passDirect8 (x8, y8);  
242    }
243    GET_TIME(tms2);   
244    HOW_LONG(tms2,tms1);
245
246  // ----------------------------------------
247  
248    std::cout << "Pass uint_8 param as ref"
249              << std::endl;
250
251    GET_TIME(tms1);  
252    for(i = 0 ; i< nbLoop ; i++)
253    {
254       passRef8 (x8, y8);  
255    }
256    GET_TIME(tms2);   
257    HOW_LONG(tms2,tms1);
258
259  // ----------------------------------------
260  
261    std::cout << "Pass uint_8 param as ptr"
262              << std::endl;
263
264    GET_TIME(tms1);  
265    for(i = 0 ; i< nbLoop ; i++)
266    {
267       passPtr8 (&x8, &y8);  
268    }
269    GET_TIME(tms2);   
270    HOW_LONG(tms2,tms1);
271
272  // ----------------------------------------
273    std::cout << std::endl;
274    std::cout << "Pass uint_16 param directly"
275              << std::endl;
276
277    GET_TIME(tms1);   
278    for(i = 0 ; i< nbLoop ; i++)
279    {
280       passDirect16 (x16, y16);  
281    }
282    GET_TIME(tms2);   
283    HOW_LONG(tms2,tms1);
284
285  // ----------------------------------------
286  
287    std::cout << "Pass uint_16 param as ref"
288              << std::endl;
289
290    GET_TIME(tms1);   
291    for(i = 0 ; i< nbLoop ; i++)
292    {
293       passRef16 (x16, y16);  
294    }
295    GET_TIME(tms2);   
296    HOW_LONG(tms2,tms1);
297
298  // ----------------------------------------
299  
300    std::cout << "Pass uint_16 param as ptr"
301              << std::endl;
302
303    GET_TIME(tms1);   
304    for(i = 0 ; i< nbLoop ; i++)
305    {
306       passPtr16 (&x16, &y16);  
307    }
308    GET_TIME(tms2);   
309    HOW_LONG(tms2,tms1);
310
311  // ----------------------------------------
312    std::cout << std::endl;
313    std::cout << "Pass uint_32 param directly"
314              << std::endl;
315
316    GET_TIME(tms1);  
317    for(i = 0 ; i< nbLoop ; i++)
318    {
319       passDirect32 (x32, y32);  
320    }
321    GET_TIME(tms2);   
322    HOW_LONG(tms2,tms1);
323
324  // ----------------------------------------
325  
326    std::cout << "Pass uint32_t param as ref"
327              << std::endl;
328
329    GET_TIME(tms1);    
330    for(i = 0 ; i< nbLoop ; i++)
331    {
332       passRef32 (x32, y32 );  
333    }
334    GET_TIME(tms2);   
335    HOW_LONG(tms2,tms1);
336
337  // ----------------------------------------
338  
339    std::cout << "Pass uint_32 param as ptr"
340              << std::endl;
341
342    GET_TIME(tms1);    
343    for(i = 0 ; i< nbLoop ; i++)
344    {
345       passPtr32 (&x32, &y32);  
346    }
347    GET_TIME(tms2);   
348    HOW_LONG(tms2,tms1);
349
350  // ----------------------------------------
351    std::cout << std::endl; 
352    std::cout << "Pass float param directly"
353              << std::endl;
354
355    GET_TIME(tms1);   
356    for(i = 0 ; i< nbLoop ; i++)
357    {
358       passDirectFloat (fx, fy);  
359    }
360    GET_TIME(tms2);   
361    HOW_LONG(tms2,tms1);
362
363  // ----------------------------------------
364  
365    std::cout << "Pass float param as ref"
366              << std::endl;
367
368    GET_TIME(tms1);    
369    for(i = 0 ; i< nbLoop ; i++)
370    {
371       passRefFloat (fx, fy);  
372    }
373    GET_TIME(tms2);   
374    HOW_LONG(tms2,tms1);
375
376  // ----------------------------------------
377  
378    std::cout << "Pass float param as ptr"
379              << std::endl;
380
381    GET_TIME(tms1);   
382    for(i = 0 ; i< nbLoop ; i++)
383    {
384       passPtrFloat (&fx, &fy);  
385    }
386    GET_TIME(tms2);   
387    HOW_LONG(tms2,tms1);
388
389  // ----------------------------------------
390    std::cout << std::endl; 
391    std::cout << "Pass double param directly"
392              << std::endl;
393
394    GET_TIME(tms1);   
395    for(i = 0 ; i< nbLoop ; i++)
396    {
397       passDirectDouble (dx, dy);  
398    }
399    GET_TIME(tms2);   
400    HOW_LONG(tms2,tms1);
401
402  // ----------------------------------------
403  
404    std::cout << "Pass double param as ref"
405              << std::endl;
406
407    GET_TIME(tms1);  
408    for(i = 0 ; i< nbLoop ; i++)
409    {
410       passRefDouble (dx, dy);  
411    }
412    GET_TIME(tms2);   
413    HOW_LONG(tms2,tms1);
414  // ----------------------------------------
415  
416    std::cout << "Pass double param as ptr"
417              << std::endl;
418
419    GET_TIME(tms1);  
420    for(i = 0 ; i< nbLoop ; i++)
421    {
422       passPtrDouble (&dx, &dy);  
423    }
424    GET_TIME(tms2);   
425    HOW_LONG(tms2,tms1);
426
427  
428 // ====================================================================
429   
430    std::cout << std::endl;
431    std::cout << "Exchange 2 scalars " << nbLoop << " times" << std::endl
432              << "==================="
433              << std::endl << std::endl;
434     
435  // ----------------------------------------
436  
437    std::cout << "Direct "<< std::endl;
438
439    GET_TIME(tms1);   
440    for(i = 0 ; i< nbLoop ; i++)
441    {
442       double tmp;
443       tmp=a;
444       a=b;
445       b=tmp;
446    }
447    GET_TIME(tms2);
448    HOW_LONG(tms2,tms1);  
449
450    
451  // ----------------------------------------
452  
453    std::cout << "Use a macro "<< std::endl;
454
455    GET_TIME(tms1);   
456    for(i = 0 ; i< nbLoop ; i++)
457    {
458       mswap (a,b);  
459    }
460    GET_TIME(tms2);   
461    HOW_LONG(tms2,tms1);  
462    
463  // ----------------------------------------
464  
465    std::cout << std::endl;  
466    std::cout << "Use a function, param passed by reference" << std::endl;
467
468    GET_TIME(tms1);    
469    for(i = 0 ; i< nbLoop ; i++)
470    {
471       frswap (a,b);  
472    }
473    GET_TIME(tms2);   
474    HOW_LONG(tms2,tms1); 
475    
476  // ----------------------------------------
477   
478    std::cout << "Use a function, param passed by pointer" << std::endl;
479
480    GET_TIME(tms1);  ;   
481    for(i = 0 ; i< nbLoop ; i++)
482    {
483       fpswap (&a, &b);  
484    }
485    GET_TIME(tms2);   
486    HOW_LONG(tms2,tms1); 
487    
488  // ----------------------------------------
489  
490    std::cout << std::endl;
491  
492    std::cout << "Use inline, .cxx-defined function, param passed by reference" << std::endl;
493
494    GET_TIME(tms1);  
495    for(i = 0 ; i< nbLoop ; i++)
496    {
497       ifrswap (a, b);  
498    }
499    GET_TIME(tms2);   
500    HOW_LONG(tms2,tms1);
501    
502  // ----------------------------------------
503  
504    std::cout << "Use inline, .cxx-defined function, param passed by pointer" << std::endl;
505
506    GET_TIME(tms1);     
507    for(i = 0 ; i< nbLoop ; i++)
508    {
509       ifpswap (&a, &b);  
510    }
511    GET_TIME(tms2);
512    HOW_LONG(tms2,tms1);
513
514  // ----------------------------------------
515
516    std::cout << std::endl;
517      
518 //To check the 2 following cases, we just put the two 'static' functions
519 //hifpswap and  hNoifpswap in gdcmUtil.h
520     
521    std::cout << "Use inline, .h defined, WITH inline keyword, param passed by pointer"
522              << std::endl;
523
524    gdcm::Util util;
525
526    GET_TIME(tms1);    
527    for(i = 0 ; i< nbLoop ; i++)
528    {
529       util.hifpswap (&a, &b);
530    }
531    GET_TIME(tms2);   
532    HOW_LONG(tms2,tms1);
533
534    
535  // ----------------------------------------
536
537    std::cout << "Use inline, .h defined, NO inline keyword, param passed by pointer"
538              << std::endl;
539
540    GET_TIME(tms1);     
541    for(i = 0 ; i< nbLoop ; i++)
542    {
543       util.hNoifpswap (&a, &b);
544    }
545    GET_TIME(tms2);   
546    HOW_LONG(tms2,tms1);
547
548  // ----------------------------------------
549    std::cout << std::endl;
550    
551    std::cout << "Use inline, .h defined, WITH inline keyword, param passed by pointer STATIC function"
552              << std::endl;
553
554    GET_TIME(tms1);   
555    for(i = 0 ; i< nbLoop ; i++)
556    {
557       gdcm::Util::sthifpswap (&a, &b);
558    }
559    GET_TIME(tms2);   
560    HOW_LONG(tms2,tms1);
561    
562  // ----------------------------------------
563
564    std::cout << "Use inline, .h defined, NO inline keyword, param passed by pointer STATIC function"
565              << std::endl;
566
567    GET_TIME(tms1);    
568    for(i = 0 ; i< nbLoop ; i++)
569    {
570       gdcm::Util::sthNoifpswap (&a, &b);
571    }
572    GET_TIME(tms2);   
573    HOW_LONG(tms2,tms1);
574
575    //return 1; // will generate an error, 
576              // just to allow us to see the full log in the dashboard
577    return 0;
578 }