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