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