KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > julia > perf > TestPerf


1 /***
2  * Julia: France Telecom's implementation of the Fractal API
3  * Copyright (C) 2001-2002 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: Eric.Bruneton@rd.francetelecom.com
20  *
21  * Author: Eric Bruneton
22  */

23
24 package org.objectweb.fractal.julia.perf;
25
26 import org.objectweb.fractal.api.Component;
27 import org.objectweb.fractal.api.NoSuchInterfaceException;
28 import org.objectweb.fractal.api.factory.Factory;
29 import org.objectweb.fractal.api.factory.GenericFactory;
30 import org.objectweb.fractal.api.type.ComponentType;
31 import org.objectweb.fractal.api.type.InterfaceType;
32 import org.objectweb.fractal.api.type.TypeFactory;
33
34 import org.objectweb.fractal.julia.perf.components.I;
35 import org.objectweb.fractal.julia.perf.components.C;
36
37 import org.objectweb.fractal.util.Fractal;
38
39 /**
40  * An application to test the performances of the framework. This application
41  * computes the size of empty components and compares it to the size of an empty
42  * Java object. It also computes the duration of an empty method call on a
43  * component, and compares it to the duration of an empty method call on a Java
44  * object (via a Java interface, i.e., through an opc_invokeinterface bytecode
45  * instruction). These measurements are done both with compiled and generated
46  * containers.
47  */

48
49 public class TestPerf {
50
51   /**
52    * Launches the performance measurement tests.
53    *
54    * @param args the command line arguments.
55    * @throws Exception if a problem occurs.
56    */

57
58   public static void main (final String JavaDoc[] args) throws Exception JavaDoc {
59
60     Component boot = Fractal.getBootstrapComponent();
61
62     TypeFactory tf = Fractal.getTypeFactory(boot);
63     ComponentType type = tf.createFcType(new InterfaceType[] {
64       tf.createFcItfType(
65         "s",
66         I.class.getName(),
67         false,
68         false,
69         false)
70     });
71     GenericFactory cf = Fractal.getGenericFactory(boot);
72     Component tmpl = cf.newFcInstance(
73       type, "primitiveTemplate", new Object JavaDoc[] {
74         "primitive", C.class.getName()
75       });
76
77     Component comp = Fractal.getFactory(tmpl).newFcInstance();
78     try {
79       Fractal.getLifeCycleController(comp).startFc();
80     } catch (NoSuchInterfaceException _) {
81     }
82     I i = (I)comp.getFcInterface("s");
83
84     System.out.println("Julia performances, " + args[0]);
85     computeObjectCallDuration();
86     computeComponentCallDuration(i);
87     computeEmptyObjectSize();
88     computeEmptyComponentSize(Fractal.getFactory(tmpl));
89     computeComponentTypeSize((ComponentType)comp.getFcType());
90     computeComponentCreationDuration();
91     computeTemplateCreationDuration();
92     computeTemplateInstantiationDuration(Fractal.getFactory(tmpl));
93     System.out.println();
94   }
95
96   // -------------------------------------------------------------------------
97
// Time measurements
98
// -------------------------------------------------------------------------
99

100   /**
101    * Number of method calls to execute to estimate method call durations.
102    */

103
104   private final static int NB_CALLS = 10000000;
105
106   /**
107    * Number of estimations needed to compute min, max and mean values.
108    */

109
110   private final static int LOOPS = 7;
111
112   /**
113    * Mean duration of an empty method call on an object.
114    */

115
116   private static double objectCallMean;
117
118   /**
119    * Estimates the duration of an empty method call on an object.
120    */

121
122   private static void computeObjectCallDuration () {
123     // initializes the min, max and mean value
124
double min = Long.MAX_VALUE;
125     double max = Long.MIN_VALUE;
126     double mean = 0;
127     I itf = new C();
128
129     // makes several estimations in order to compute min, max and mean
130
for (int j = 0; j < LOOPS; ++j) {
131       int i = NB_CALLS;
132       double dt = System.currentTimeMillis();
133       while (i > 0) {
134         i = itf.m(i);
135       }
136       dt = 1000 * (System.currentTimeMillis() - dt) / NB_CALLS;
137       // the first iterations are not taken into account (warm up)
138
if (j > 1) {
139         // updates the min, max and mean values
140
min = Math.min(dt, min);
141         max = Math.max(dt, max);
142         mean += dt;
143       }
144     }
145     // computes the mean value in micro-seconds
146
mean = mean / (LOOPS - 2);
147     // computes the variation in nano-seconds
148
double delta = 1000 * Math.max(max - mean, mean - min);
149     // prints the results
150
System.out.print("method call = ");
151     System.out.println(format(mean) + " µs (+/- " + format(delta) + " ns)");
152     // stores the min, max and mean value to compute overhead of components
153
// (see computeComponentCallDuration)
154
objectCallMean = mean;
155   }
156
157   /**
158    * Estimates the duration of an empty method call on a component.
159    *
160    * @param itf the interface to be used for measurements.
161    */

162
163   private static void computeComponentCallDuration (I itf) {
164     // initializes the min, max and mean value
165
double min = Long.MAX_VALUE;
166     double max = Long.MIN_VALUE;
167     double mean = 0;
168
169     // makes several estimations in order to compute min, max and mean
170
for (int j = 0; j < LOOPS; ++j) {
171       int i = NB_CALLS;
172       double dt = System.currentTimeMillis();
173       while (i > 0) {
174         i = itf.m(i);
175       }
176       dt = 1000 * (System.currentTimeMillis() - dt) / NB_CALLS;
177       // the first iterations are not taken into account (warm up)
178
if (j > 1) {
179         // updates the min, max and mean values
180
min = Math.min(dt, min);
181         max = Math.max(dt, max);
182         mean += dt;
183       }
184     }
185     // computes the mean value in micro-seconds
186
mean = mean / (LOOPS - 2);
187     // computes the variation in nano-seconds
188
double delta = 1000 * Math.max(max - mean, mean - min);
189     // compute the mean overhead, due to the interception code
190
double overhead = mean - objectCallMean;
191     // prints the results
192
System.out.print("component call = ");
193     System.out.print(format(mean) + " µs (+/- " + format(delta) + " ns)");
194     System.out.print(" => +" + format(overhead) + " µs");
195     System.out.println(" (" + format(overhead / objectCallMean) + " calls)");
196   }
197
198   /**
199    * Estimates the time needed to create a component.
200    *
201    * @throws Exception if a problem occurs.
202    */

203
204   private static void computeComponentCreationDuration () throws Exception JavaDoc {
205     Component boot = Fractal.getBootstrapComponent();
206     // initializes the min, max and mean value
207
double min = Long.MAX_VALUE;
208     double max = Long.MIN_VALUE;
209     double mean = 0;
210     // makes several estimations in order to compute min, max and mean
211
for (int j = 0; j < LOOPS; ++j) {
212       int i = 0;
213       double dt = System.currentTimeMillis();
214       while (i < NB_INSTANCES_2) {
215         TypeFactory tf = Fractal.getTypeFactory(boot);
216         GenericFactory cf = Fractal.getGenericFactory(boot);
217         ComponentType type = tf.createFcType(new InterfaceType[] {
218           tf.createFcItfType(
219             "s",
220             I.class.getName(),
221             false,
222             false,
223             false)
224         });
225         cf.newFcInstance(type, "primitive", C.class.getName());
226         ++i;
227       }
228       dt = (System.currentTimeMillis() - dt) / NB_INSTANCES_2;
229       // the first iterations are not taken into account (warm up)
230
if (j > 1) {
231         // updates the min, max and mean values
232
min = Math.min(dt, min);
233         max = Math.max(dt, max);
234         mean += dt;
235       }
236     }
237     // computes the mean value in milli-seconds
238
mean = mean / (LOOPS - 2);
239     // computes the variation in micro-seconds
240
double delta = 1000 * Math.max(max - mean, mean - min);
241     // prints the results
242
System.out.print("component creation = ");
243     System.out.println(format(mean) + " ms (+/- " + format(delta) + " µs)");
244   }
245
246   /**
247    * Estimates the time needed to create a component template.
248    *
249    * @throws Exception if a problem occurs.
250    */

251
252   private static void computeTemplateCreationDuration () throws Exception JavaDoc {
253     Component boot = Fractal.getBootstrapComponent();
254     // initializes the min, max and mean value
255
double min = Long.MAX_VALUE;
256     double max = Long.MIN_VALUE;
257     double mean = 0;
258     // makes several estimations in order to compute min, max and mean
259
for (int j = 0; j < LOOPS; ++j) {
260       int i = 0;
261       double dt = System.currentTimeMillis();
262       while (i < NB_INSTANCES_2) {
263         TypeFactory tf = Fractal.getTypeFactory(boot);
264         ComponentType type = tf.createFcType(new InterfaceType[] {
265           tf.createFcItfType(
266             "s",
267             I.class.getName(),
268             false,
269             false,
270             false)
271         });
272         GenericFactory cf = Fractal.getGenericFactory(boot);
273         cf.newFcInstance(
274           type, "primitiveTemplate", new Object JavaDoc[] {
275             "primitive", C.class.getName()
276           });
277         ++i;
278       }
279       dt = (System.currentTimeMillis() - dt) / NB_INSTANCES_2;
280       // the first iterations are not taken into account (warm up)
281
if (j > 1) {
282         // updates the min, max and mean values
283
min = Math.min(dt, min);
284         max = Math.max(dt, max);
285         mean += dt;
286       }
287     }
288     // computes the mean value in milli-seconds
289
mean = mean / (LOOPS - 2);
290     // computes the variation in micro-seconds
291
double delta = 1000 * Math.max(max - mean, mean - min);
292     // prints the results
293
System.out.print("template creation = ");
294     System.out.println(format(mean) + " ms (+/- " + format(delta) + " µs)");
295   }
296
297   /**
298    * Estimates the time needed to instantiate a component template.
299    *
300    * @param tmpl the component template to be used for the measurements.
301    * @throws Exception if a problem occurs.
302    */

303
304   private static void computeTemplateInstantiationDuration (Factory tmpl)
305     throws Exception JavaDoc
306   {
307     // initializes the min, max and mean value
308
double min = Long.MAX_VALUE;
309     double max = Long.MIN_VALUE;
310     double mean = 0;
311     // makes several estimations in order to compute min, max and mean
312
for (int j = 0; j < LOOPS; ++j) {
313       int i = 0;
314       double dt = System.currentTimeMillis();
315       while (i < NB_INSTANCES_2) {
316         tmpl.newFcInstance();
317         ++i;
318       }
319       dt = (System.currentTimeMillis() - dt) / NB_INSTANCES_2;
320       // the first iterations are not taken into account (warm up)
321
if (j > 1) {
322         // updates the min, max and mean values
323
min = Math.min(dt, min);
324         max = Math.max(dt, max);
325         mean += dt;
326       }
327     }
328     // computes the mean value in milli-seconds
329
mean = mean / (LOOPS - 2);
330     // computes the variation in micro-seconds
331
double delta = 1000 * Math.max(max - mean, mean - min);
332     // prints the results
333
System.out.print("template instantiation = ");
334     System.out.println(format(mean) + " ms (+/- " + format(delta) + " µs)");
335   }
336
337   // -------------------------------------------------------------------------
338
// Memory measurements
339
// -------------------------------------------------------------------------
340

341   /**
342    * Number of instances to instantiate to estimate object and component sizes.
343    */

344
345   private final static int NB_INSTANCES_1 = 100;
346
347   /**
348    * Number of instances to estimate object and component creation durations.
349    */

350
351   private final static int NB_INSTANCES_2 = 1000;
352
353   /**
354    * Estimated size of an empty object.
355    */

356
357   private static long objectSize;
358
359   /**
360    * Computes the size of an empty object.
361    */

362
363   private static void computeEmptyObjectSize () {
364     // makes a first estimate
365
long oldSize;
366     long newSize = estimateEmptyObjectSize();
367     //System.err.println("SIZE ESTIMATE " + newSize);
368
do {
369       // makes a new estimate
370
oldSize = newSize;
371       newSize = estimateEmptyObjectSize();
372       //System.err.println("SIZE ESTIMATE " + newSize);
373
// loop until two consecutive estimates are equal
374
} while (newSize != oldSize);
375     // prints the results
376
System.out.print("empty object = ");
377     System.out.println(newSize + " bytes (" + (newSize / 4) + " words)");
378     // stores the result to compute the overhead of components
379
// (see computeEmptyComponentSize)
380
objectSize = newSize;
381   }
382
383   /**
384    * Estimates the size of an empty object.
385    *
386    * @return the estimated size.
387    */

388
389   private static long estimateEmptyObjectSize () {
390     long min = 0;
391     while (true) {
392       min = freeMem(min);
393       Object JavaDoc[] instances = new Object JavaDoc[NB_INSTANCES_1];
394       long start = freeMem(0);
395       for (int i = 0; i < instances.length; ++i) {
396         instances[i] = new C();
397       }
398       long freeMem = freeMem(0);
399       for (int i = 0; i < instances.length; ++i) {
400         instances[i] = null;
401       }
402       long end = freeMem(freeMem);
403       /*
404       System.err.println("FREE MEM BEFORE INSTANTIATE " + start);
405       System.err.println("FREE MEM AFTER INSTANTIATE " + freeMem);
406       System.err.println("FREE MEM AFTER GC " + end);
407       */

408       if (Math.abs(end - start) < NB_INSTANCES_1) {
409         return (end - freeMem) / NB_INSTANCES_1;
410       }
411     }
412   }
413
414   /**
415    * Computes the size of an empty component.
416    *
417    * @param tmpl the template to be used for the measurements.
418    * @throws Exception if a problem occurs.
419    */

420
421   private static void computeEmptyComponentSize (Factory tmpl)
422     throws Exception JavaDoc
423   {
424     // makes a first estimate
425
long oldSize;
426     long newSize = estimateEmptyComponentSize(tmpl);
427     //System.err.println("SIZE ESTIMATE " + newSize);
428
do {
429       // makes a new estimate
430
oldSize = newSize;
431       newSize = estimateEmptyComponentSize(tmpl);
432       //System.err.println("SIZE ESTIMATE " + newSize);
433
// loop until two consecutive estimates are equal
434
} while (newSize != oldSize);
435     // prints the results
436
System.out.print("empty component = ");
437     System.out.print(newSize + " bytes (" + (newSize / 4) + " words)");
438     System.out.println(" => + " + (newSize - objectSize) / 4 + " words");
439   }
440
441   /**
442    * Estimates the size of an empty component.
443    *
444    * @param tmpl the template to be used for the measurements.
445    * @return the estimated size.
446    * @throws Exception if a problem occurs.
447    */

448
449   private static long estimateEmptyComponentSize (Factory tmpl)
450     throws Exception JavaDoc
451   {
452     long min = 0;
453     while (true) {
454       min = freeMem(min);
455       Object JavaDoc[] instances = new Object JavaDoc[NB_INSTANCES_1];
456       long start = freeMem(0);
457       for (int i = 0; i < instances.length; ++i) {
458         instances[i] = tmpl.newFcInstance();
459       }
460       long freeMem = freeMem(0);
461       for (int i = 0; i < instances.length; ++i) {
462         instances[i] = null;
463       }
464       long end = freeMem(freeMem);
465       /*
466       System.err.println("FREE MEM BEFORE INSTANTIATE " + start);
467       System.err.println("FREE MEM AFTER INSTANTIATE " + freeMem);
468       System.err.println("FREE MEM AFTER GC " + end);
469       */

470       if (Math.abs(end - start) < NB_INSTANCES_1) {
471         return (end - freeMem) / NB_INSTANCES_1;
472       }
473     }
474   }
475
476   /**
477    * Computes the size of a component type.
478    *
479    * @param type the component type whose size must be computed.
480    * @throws Exception if a problem occurs.
481    */

482
483   private static void computeComponentTypeSize (ComponentType type)
484     throws Exception JavaDoc
485   {
486     // makes a first estimate
487
long oldSize;
488     long newSize = estimateComponentTypeSize(type);
489     //System.err.println("SIZE ESTIMATE " + newSize);
490
do {
491       // makes a new estimate
492
oldSize = newSize;
493       newSize = estimateComponentTypeSize(type);
494       //System.err.println("SIZE ESTIMATE " + newSize);
495
// loop until two consecutive estimates are equal
496
} while (newSize != oldSize);
497     // prints the results
498
int n = type.getFcInterfaceTypes().length;
499     System.out.print("component type (" + n + " interfaces) = ");
500     System.out.println(newSize + " bytes (" + (newSize / 4) + " words)");
501   }
502
503   /**
504    * Estimates the size of a component type.
505    *
506    * @param type the component type whose size must be estimated.
507    * @return the estimated size.
508    * @throws Exception if a problem occurs.
509    */

510
511   private static long estimateComponentTypeSize (ComponentType type)
512     throws Exception JavaDoc
513   {
514     TypeFactory tf = Fractal.getTypeFactory(Fractal.getBootstrapComponent());
515     long min = 0;
516     while (true) {
517       min = freeMem(min);
518       Object JavaDoc[] instances = new Object JavaDoc[NB_INSTANCES_1];
519       long start = freeMem(0);
520       for (int i = 0; i < instances.length; ++i) {
521         instances[i] = clone(tf, type);
522       }
523       long freeMem = freeMem(0);
524       for (int i = 0; i < instances.length; ++i) {
525         instances[i] = null;
526       }
527       long end = freeMem(freeMem);
528       /*
529       System.err.println("FREE MEM BEFORE INSTANTIATE " + start);
530       System.err.println("FREE MEM AFTER INSTANTIATE " + freeMem);
531       System.err.println("FREE MEM AFTER GC " + end);
532       */

533       if (Math.abs(end - start) < NB_INSTANCES_1) {
534         return (end - freeMem) / NB_INSTANCES_1;
535       }
536     }
537   }
538
539   /**
540    * Estimates the amount of free memory.
541    *
542    * @param min the expected minimal amount of free memory
543    * @return the estimated amount of free memory.
544    */

545
546   private static long freeMem (long min) {
547     Runtime JavaDoc rt = Runtime.getRuntime();
548     // gets the amount of free memory, after a garbage collection
549
rt.gc();
550     long oldFreeMem;
551     long newFreeMem = rt.freeMemory();
552     while (true) {
553       // gets the amount of free memory again, after another garbage collection
554
rt.gc();
555       oldFreeMem = newFreeMem;
556       newFreeMem = rt.freeMemory();
557       // loop until two consecutive results are equal above 'min'
558
if (newFreeMem == oldFreeMem && newFreeMem >= min) {
559         return newFreeMem;
560       }
561     }
562   }
563
564   // -------------------------------------------------------------------------
565
// Utility methods
566
// -------------------------------------------------------------------------
567

568   /**
569    * Converts the given double to a String.
570    *
571    * @param d a double.
572    * @return the given double as a String.
573    */

574
575   private static String JavaDoc format (final double d) {
576     return Float.toString((float)d);
577   }
578
579   /**
580    * Clones a component type.
581    *
582    * @param tf the type factory to be used to create the clone.
583    * @param type the component type to be cloned.
584    * @return a clone of the given component type.
585    * @throws Exception if a problem occurs.
586    */

587
588   private static ComponentType clone (
589     final TypeFactory tf,
590     final ComponentType type) throws Exception JavaDoc
591   {
592     InterfaceType[] itfTypes = type.getFcInterfaceTypes();
593     InterfaceType[] cloneItfTypes = new InterfaceType[itfTypes.length];
594     for (int i = 0; i < itfTypes.length; ++i) {
595       InterfaceType itfType = itfTypes[i];
596       cloneItfTypes[i] = tf.createFcItfType(
597         new String JavaDoc(itfType.getFcItfName().toCharArray()),
598         new String JavaDoc(itfType.getFcItfSignature().toCharArray()),
599         itfType.isFcClientItf(),
600         itfType.isFcOptionalItf(),
601         itfType.isFcCollectionItf());
602     }
603     return tf.createFcType(cloneItfTypes);
604   }
605 }
606
Popular Tags