Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / performance-tests / Anyop / anyop.cpp
blobd7f0420654f327643ec355f3b834809417dc5932
2 //=============================================================================
3 /**
4 * @file anyop.cpp
6 * Modified from anyop.cpp in Param_Test to benchmark Any insertion and
7 * extraction operators for various IDL types.
9 * @author Carlos O'Ryan Jeff Parsons
11 //=============================================================================
14 #include "testC.h"
15 #include "tao/debug.h"
16 #include "tao/AnyTypeCode/Any.h"
17 #include "tao/Stub.h"
18 #include "tao/Object_T.h"
19 #include "ace/Get_Opt.h"
20 #include "ace/High_Res_Timer.h"
21 #include "ace/Stats.h"
22 #include "ace/Throughput_Stats.h"
23 #include "ace/Sample_History.h"
24 #include "ace/Sched_Params.h"
26 int
27 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
29 int priority =
30 (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
31 + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
33 ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO,
34 priority,
35 ACE_SCOPE_PROCESS));
37 int n = 50000;
38 int insertion = 1;
40 try
42 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
44 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("dien:"));
45 int opt;
47 while ((opt = get_opt ()) != EOF)
49 switch (opt)
51 case 'd':
52 TAO_debug_level++;
53 break;
54 case 'i':
55 insertion = 1;
56 break;
57 case 'e':
58 insertion = 0;
59 break;
60 case 'n':
61 n = ACE_OS::atoi (get_opt.opt_arg ());
62 break;
63 case '?':
64 default:
65 ACE_DEBUG ((LM_DEBUG,
66 "Usage: %s "
67 "-d debug"
68 "-n <num> "
69 "\n",
70 argv[0]));
71 return -1;
75 CORBA::Boolean result = 0;
76 int j;
79 CORBA::Object_var obj =
80 orb->string_to_object ("corbaloc:iiop:localhost:1234/Foo/Bar");
82 Param_Test_var param_test =
83 TAO::Narrow_Utils<Param_Test>::unchecked_narrow (obj.in ());
84 TAO_Stub *stub = param_test->_stubobj ();
85 stub->type_id = CORBA::string_dup ("IDL:Param_Test:1.0");
87 ACE_Sample_History history (n);
88 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
90 for (j = 0; j != n; ++j)
92 CORBA::Any any;
94 if (insertion == 1)
96 ACE_hrtime_t start = ACE_OS::gethrtime ();
98 any <<= param_test.in ();
100 ACE_hrtime_t now = ACE_OS::gethrtime ();
101 history.sample (now - start);
103 Param_Test_ptr o;
105 result = any >>= o;
107 else
109 any <<= param_test.in ();
111 Param_Test_ptr o;
113 ACE_hrtime_t start = ACE_OS::gethrtime ();
115 result = any >>= o;
117 ACE_hrtime_t now = ACE_OS::gethrtime ();
118 history.sample (now - start);
122 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
124 if (insertion == 1)
126 ACE_DEBUG ((LM_DEBUG,
127 "Objref insertion test finished\n"));
129 else
131 ACE_DEBUG ((LM_DEBUG,
132 "Objref extraction test finished\n"));
135 ACE_DEBUG ((LM_DEBUG,
136 "High resolution timer calibration...."));
137 ACE_High_Res_Timer::global_scale_factor_type gsf =
138 ACE_High_Res_Timer::global_scale_factor ();
139 ACE_DEBUG ((LM_DEBUG,
140 "done\n"));
142 ACE_Basic_Stats stats;
143 history.collect_basic_stats (stats);
144 stats.dump_results (ACE_TEXT("Total"), gsf);
146 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
147 gsf,
148 test_end - test_start,
149 stats.samples_count ());
152 ACE_DEBUG ((LM_DEBUG, "\n"));
155 ACE_Sample_History history (n);
156 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
158 for (j = 0; j != n; ++j)
160 CORBA::Any any;
161 CORBA::Short i = 123;
163 if (insertion == 1)
165 ACE_hrtime_t start = ACE_OS::gethrtime ();
167 any <<= i;
169 ACE_hrtime_t now = ACE_OS::gethrtime ();
170 history.sample (now - start);
172 CORBA::Short o;
174 result = any >>= o;
176 else
178 any <<= i;
180 CORBA::Short o;
182 ACE_hrtime_t start = ACE_OS::gethrtime ();
184 result = any >>= o;
186 ACE_hrtime_t now = ACE_OS::gethrtime ();
187 history.sample (now - start);
191 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
193 if (insertion == 1)
195 ACE_DEBUG ((LM_DEBUG,
196 "Short insertion test finished\n"));
198 else
200 ACE_DEBUG ((LM_DEBUG,
201 "Short extraction test finished\n"));
203 ACE_DEBUG ((LM_DEBUG,
204 "High resolution timer calibration...."));
205 ACE_High_Res_Timer::global_scale_factor_type gsf =
206 ACE_High_Res_Timer::global_scale_factor ();
207 ACE_DEBUG ((LM_DEBUG,
208 "done\n"));
210 ACE_Basic_Stats stats;
211 history.collect_basic_stats (stats);
212 stats.dump_results (ACE_TEXT("Total"), gsf);
214 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
215 gsf,
216 test_end - test_start,
217 stats.samples_count ());
220 ACE_DEBUG ((LM_DEBUG, "\n"));
223 ACE_Sample_History history (n);
224 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
226 for (j = 0; j != n; ++j)
228 CORBA::Any any;
229 CORBA::Long i = 123;
231 if (insertion == 1)
233 ACE_hrtime_t start = ACE_OS::gethrtime ();
235 any <<= i;
237 ACE_hrtime_t now = ACE_OS::gethrtime ();
238 history.sample (now - start);
240 CORBA::Long o;
242 result = any >>= o;
244 else
246 any <<= i;
248 CORBA::Long o;
250 ACE_hrtime_t start = ACE_OS::gethrtime ();
252 result = any >>= o;
254 ACE_hrtime_t now = ACE_OS::gethrtime ();
255 history.sample (now - start);
259 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
261 if (insertion == 1)
263 ACE_DEBUG ((LM_DEBUG,
264 "Long insertion test finished\n"));
266 else
268 ACE_DEBUG ((LM_DEBUG,
269 "Long extraction test finished\n"));
272 ACE_DEBUG ((LM_DEBUG,
273 "High resolution timer calibration...."));
274 ACE_High_Res_Timer::global_scale_factor_type gsf =
275 ACE_High_Res_Timer::global_scale_factor ();
276 ACE_DEBUG ((LM_DEBUG,
277 "done\n"));
279 ACE_Basic_Stats stats;
280 history.collect_basic_stats (stats);
281 stats.dump_results (ACE_TEXT("Total"), gsf);
283 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
284 gsf,
285 test_end - test_start,
286 stats.samples_count ());
289 ACE_DEBUG ((LM_DEBUG, "\n"));
292 ACE_Sample_History history (n);
293 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
295 for (j = 0; j != n; ++j)
297 CORBA::Any any;
298 CORBA::Double i = 123;
300 if (insertion == 1)
302 ACE_hrtime_t start = ACE_OS::gethrtime ();
304 any <<= i;
306 ACE_hrtime_t now = ACE_OS::gethrtime ();
307 history.sample (now - start);
309 CORBA::Double o;
311 result = any >>= o;
313 else
315 any <<= i;
317 CORBA::Double o;
319 ACE_hrtime_t start = ACE_OS::gethrtime ();
321 result = any >>= o;
323 ACE_hrtime_t now = ACE_OS::gethrtime ();
324 history.sample (now - start);
328 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
330 if (insertion == 1)
332 ACE_DEBUG ((LM_DEBUG,
333 "Double insertion test finished\n"));
335 else
337 ACE_DEBUG ((LM_DEBUG,
338 "Double extraction test finished\n"));
341 ACE_DEBUG ((LM_DEBUG,
342 "High resolution timer calibration...."));
343 ACE_High_Res_Timer::global_scale_factor_type gsf =
344 ACE_High_Res_Timer::global_scale_factor ();
345 ACE_DEBUG ((LM_DEBUG,
346 "done\n"));
348 ACE_Basic_Stats stats;
349 history.collect_basic_stats (stats);
350 stats.dump_results (ACE_TEXT("Total"), gsf);
352 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
353 gsf,
354 test_end - test_start,
355 stats.samples_count ());
358 ACE_DEBUG ((LM_DEBUG, "\n"));
361 Param_Test::Fixed_Struct i;
362 i.l = -7;
363 i.c = 'c';
364 i.s = 5;
365 i.o = 255;
366 i.f = 2.3f;
367 i.b = 0;
368 i.d = 3.1416;
370 ACE_Sample_History history (n);
371 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
373 for (j = 0; j != n; ++j)
375 CORBA::Any any;
377 if (insertion == 1)
379 ACE_hrtime_t start = ACE_OS::gethrtime ();
381 any <<= i;
383 ACE_hrtime_t now = ACE_OS::gethrtime ();
384 history.sample (now - start);
386 const Param_Test::Fixed_Struct *o = 0;
388 result = any >>= o;
390 else
392 any <<= i;
394 const Param_Test::Fixed_Struct *o = 0;
396 ACE_hrtime_t start = ACE_OS::gethrtime ();
398 result = any >>= o;
400 ACE_hrtime_t now = ACE_OS::gethrtime ();
401 history.sample (now - start);
405 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
407 if (insertion == 1)
409 ACE_DEBUG ((LM_DEBUG,
410 "Struct copying insertion test finished\n"));
412 else
414 ACE_DEBUG ((LM_DEBUG,
415 "Struct extraction test finished\n"));
418 ACE_DEBUG ((LM_DEBUG,
419 "High resolution timer calibration...."));
420 ACE_High_Res_Timer::global_scale_factor_type gsf =
421 ACE_High_Res_Timer::global_scale_factor ();
422 ACE_DEBUG ((LM_DEBUG,
423 "done\n"));
425 ACE_Basic_Stats stats;
426 history.collect_basic_stats (stats);
427 stats.dump_results (ACE_TEXT("Total"), gsf);
429 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
430 gsf,
431 test_end - test_start,
432 stats.samples_count ());
435 ACE_DEBUG ((LM_DEBUG, "\n"));
438 ACE_Sample_History history (n);
439 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
440 for (j = 0; j != n; ++j)
442 CORBA::Any any;
443 Param_Test::Fixed_Struct *i = 0;
444 ACE_NEW_RETURN (i,
445 Param_Test::Fixed_Struct,
446 -1);
447 i->l = -7;
448 i->c = 'c';
449 i->s = 5;
450 i->o = 255;
451 i->f = 2.3f;
452 i->b = 0;
453 i->d = 3.1416;
455 if (insertion == 1)
457 ACE_hrtime_t start = ACE_OS::gethrtime ();
459 any <<= i;
461 ACE_hrtime_t now = ACE_OS::gethrtime ();
462 history.sample (now - start);
464 const Param_Test::Fixed_Struct *o = 0;
466 result = any >>= o;
468 else
470 any <<= i;
472 const Param_Test::Fixed_Struct *o = 0;
474 ACE_hrtime_t start = ACE_OS::gethrtime ();
476 result = any >>= o;
478 ACE_hrtime_t now = ACE_OS::gethrtime ();
479 history.sample (now - start);
483 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
485 if (insertion == 1)
487 ACE_DEBUG ((LM_DEBUG,
488 "Struct non-copying insertion test finished\n"));
490 else
492 ACE_DEBUG ((LM_DEBUG,
493 "Struct extraction test finished\n"));
496 ACE_DEBUG ((LM_DEBUG,
497 "High resolution timer calibration...."));
498 ACE_High_Res_Timer::global_scale_factor_type gsf =
499 ACE_High_Res_Timer::global_scale_factor ();
500 ACE_DEBUG ((LM_DEBUG,
501 "done\n"));
503 ACE_Basic_Stats stats;
504 history.collect_basic_stats (stats);
505 stats.dump_results (ACE_TEXT("Total"), gsf);
507 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
508 gsf,
509 test_end - test_start,
510 stats.samples_count ());
513 ACE_DEBUG ((LM_DEBUG, "\n"));
516 CORBA::ULong len = 1024;
517 Param_Test::Long_Seq i (len);
518 i.length (len);
520 for (CORBA::ULong k = 0; k < len; ++k)
522 i[k] = 11;
525 ACE_Sample_History history (n);
526 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
528 for (j = 0; j != n; ++j)
530 CORBA::Any any;
532 if (insertion == 1)
534 ACE_hrtime_t start = ACE_OS::gethrtime ();
536 any <<= i;
538 ACE_hrtime_t now = ACE_OS::gethrtime ();
539 history.sample (now - start);
541 const Param_Test::Long_Seq *o = 0;
543 result = any >>= o;
545 else
547 any <<= i;
549 const Param_Test::Long_Seq *o = 0;
551 ACE_hrtime_t start = ACE_OS::gethrtime ();
553 result = any >>= o;
555 ACE_hrtime_t now = ACE_OS::gethrtime ();
556 history.sample (now - start);
560 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
562 if (insertion == 1)
564 ACE_DEBUG ((LM_DEBUG,
565 "Sequence copying insertion test finished\n"));
567 else
569 ACE_DEBUG ((LM_DEBUG,
570 "Sequence extraction test finished\n"));
573 ACE_DEBUG ((LM_DEBUG,
574 "High resolution timer calibration...."));
575 ACE_High_Res_Timer::global_scale_factor_type gsf =
576 ACE_High_Res_Timer::global_scale_factor ();
577 ACE_DEBUG ((LM_DEBUG,
578 "done\n"));
580 ACE_Basic_Stats stats;
581 history.collect_basic_stats (stats);
582 stats.dump_results (ACE_TEXT("Total"), gsf);
584 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
585 gsf,
586 test_end - test_start,
587 stats.samples_count ());
590 ACE_DEBUG ((LM_DEBUG, "\n"));
593 CORBA::ULong len = 1024;
594 ACE_Sample_History history (n);
595 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
596 for (j = 0; j != n; ++j)
598 CORBA::Any any;
599 Param_Test::Long_Seq *i = 0;
600 ACE_NEW_RETURN (i,
601 Param_Test::Long_Seq (len),
602 -1);
603 i->length (len);
605 for (CORBA::ULong k = 0; k < len; ++k)
607 (*i)[k] = 11;
610 if (insertion == 1)
612 ACE_hrtime_t start = ACE_OS::gethrtime ();
614 any <<= i;
616 ACE_hrtime_t now = ACE_OS::gethrtime ();
617 history.sample (now - start);
619 const Param_Test::Long_Seq *o = 0;
621 result = any >>= o;
623 else
625 any <<= i;
627 const Param_Test::Long_Seq *o = 0;
629 ACE_hrtime_t start = ACE_OS::gethrtime ();
631 result = any >>= o;
633 ACE_hrtime_t now = ACE_OS::gethrtime ();
634 history.sample (now - start);
638 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
640 if (insertion == 1)
642 ACE_DEBUG ((LM_DEBUG,
643 "Sequence non-copying insertion test finished\n"));
645 else
647 ACE_DEBUG ((LM_DEBUG,
648 "Sequence extraction test finished\n"));
651 ACE_DEBUG ((LM_DEBUG,
652 "High resolution timer calibration...."));
653 ACE_High_Res_Timer::global_scale_factor_type gsf =
654 ACE_High_Res_Timer::global_scale_factor ();
655 ACE_DEBUG ((LM_DEBUG,
656 "done\n"));
658 ACE_Basic_Stats stats;
659 history.collect_basic_stats (stats);
660 stats.dump_results (ACE_TEXT("Total"), gsf);
662 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
663 gsf,
664 test_end - test_start,
665 stats.samples_count ());
668 ACE_DEBUG ((LM_DEBUG, "\n"));
671 ACE_Sample_History history (n);
672 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
674 for (j = 0; j != n; ++j)
676 CORBA::Any any;
677 CORBA::Any i;
678 i <<= CORBA::Short (123);
680 if (insertion == 1)
682 ACE_hrtime_t start = ACE_OS::gethrtime ();
684 any <<= i;
686 ACE_hrtime_t now = ACE_OS::gethrtime ();
687 history.sample (now - start);
689 const CORBA::Any *o;
690 CORBA::Short oo;
692 result = any >>= o;
693 result = *o >>= oo;
695 else
697 any <<= i;
699 const CORBA::Any *o;
700 CORBA::Short oo;
702 ACE_hrtime_t start = ACE_OS::gethrtime ();
704 result = any >>= o;
706 ACE_hrtime_t now = ACE_OS::gethrtime ();
707 history.sample (now - start);
709 result = *o >>= oo;
713 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
715 if (insertion == 1)
717 ACE_DEBUG ((LM_DEBUG,
718 "Any copying insertion test finished\n"));
720 else
722 ACE_DEBUG ((LM_DEBUG,
723 "Any extraction test finished\n"));
726 ACE_DEBUG ((LM_DEBUG,
727 "High resolution timer calibration...."));
728 ACE_High_Res_Timer::global_scale_factor_type gsf =
729 ACE_High_Res_Timer::global_scale_factor ();
730 ACE_DEBUG ((LM_DEBUG,
731 "done\n"));
733 ACE_Basic_Stats stats;
734 history.collect_basic_stats (stats);
735 stats.dump_results (ACE_TEXT("Total"), gsf);
737 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
738 gsf,
739 test_end - test_start,
740 stats.samples_count ());
743 ACE_DEBUG ((LM_DEBUG, "\n"));
746 ACE_Sample_History history (n);
747 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
749 for (j = 0; j != n; ++j)
751 CORBA::Any any;
752 CORBA::Any *i = 0;
753 ACE_NEW_RETURN (i,
754 CORBA::Any,
755 -1);
756 *i <<= CORBA::Short (123);
758 if (insertion == 1)
760 ACE_hrtime_t start = ACE_OS::gethrtime ();
762 any <<= i;
764 ACE_hrtime_t now = ACE_OS::gethrtime ();
765 history.sample (now - start);
767 const CORBA::Any *o;
768 CORBA::Short oo;
770 result = any >>= o;
771 result = *o >>= oo;
773 else
775 any <<= i;
777 const CORBA::Any *o;
778 CORBA::Short oo;
780 ACE_hrtime_t start = ACE_OS::gethrtime ();
782 result = any >>= o;
784 ACE_hrtime_t now = ACE_OS::gethrtime ();
785 history.sample (now - start);
787 result = *o >>= oo;
791 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
793 if (insertion == 1)
795 ACE_DEBUG ((LM_DEBUG,
796 "Any non-copying insertion test finished\n"));
798 else
800 ACE_DEBUG ((LM_DEBUG,
801 "Any extraction test finished\n"));
804 ACE_DEBUG ((LM_DEBUG,
805 "High resolution timer calibration...."));
806 ACE_High_Res_Timer::global_scale_factor_type gsf =
807 ACE_High_Res_Timer::global_scale_factor ();
808 ACE_DEBUG ((LM_DEBUG,
809 "done\n"));
811 ACE_Basic_Stats stats;
812 history.collect_basic_stats (stats);
813 stats.dump_results (ACE_TEXT("Total"), gsf);
815 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
816 gsf,
817 test_end - test_start,
818 stats.samples_count ());
821 ACE_DEBUG ((LM_DEBUG, "\n"));
824 ACE_Sample_History history (n);
825 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
827 for (j = 0; j != n; ++j)
829 CORBA::Any any;
830 const char i[] = "1234567890";
832 if (insertion == 1)
834 ACE_hrtime_t start = ACE_OS::gethrtime ();
836 any <<= i;
838 ACE_hrtime_t now = ACE_OS::gethrtime ();
839 history.sample (now - start);
841 const char *o;
843 result = any >>= o;
845 else
847 any <<= i;
849 const char *o;
851 ACE_hrtime_t start = ACE_OS::gethrtime ();
853 result = any >>= o;
855 ACE_hrtime_t now = ACE_OS::gethrtime ();
856 history.sample (now - start);
860 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
862 if (insertion == 1)
864 ACE_DEBUG ((LM_DEBUG,
865 "String insertion test finished\n"));
867 else
869 ACE_DEBUG ((LM_DEBUG,
870 "String extraction test finished\n"));
873 ACE_TEST_ASSERT (result);
875 ACE_DEBUG ((LM_DEBUG,
876 "High resolution timer calibration...."));
877 ACE_High_Res_Timer::global_scale_factor_type gsf =
878 ACE_High_Res_Timer::global_scale_factor ();
879 ACE_DEBUG ((LM_DEBUG,
880 "done\n"));
882 ACE_Basic_Stats stats;
883 history.collect_basic_stats (stats);
884 stats.dump_results (ACE_TEXT("Total"), gsf);
886 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
887 gsf,
888 test_end - test_start,
889 stats.samples_count ());
892 ACE_DEBUG ((LM_DEBUG, "\n"));
895 ACE_Sample_History history (n);
896 ACE_hrtime_t test_start = ACE_OS::gethrtime ();
898 for (j = 0; j != n; ++j)
900 CORBA::Any any;
901 const char i[] = "1234567890";
902 any <<= i;
903 CORBA::Any copy;
905 ACE_hrtime_t start = ACE_OS::gethrtime ();
907 copy = any;
909 ACE_hrtime_t now = ACE_OS::gethrtime ();
910 history.sample (now - start);
913 ACE_hrtime_t test_end = ACE_OS::gethrtime ();
915 ACE_DEBUG ((LM_DEBUG,
916 "Copy test finished\n"));
917 ACE_DEBUG ((LM_DEBUG,
918 "High resolution timer calibration...."));
919 ACE_High_Res_Timer::global_scale_factor_type gsf =
920 ACE_High_Res_Timer::global_scale_factor ();
921 ACE_DEBUG ((LM_DEBUG,
922 "done\n"));
924 ACE_Basic_Stats stats;
925 history.collect_basic_stats (stats);
926 stats.dump_results (ACE_TEXT("Total"), gsf);
928 ACE_Throughput_Stats::dump_throughput (ACE_TEXT("Total"),
929 gsf,
930 test_end - test_start,
931 stats.samples_count ());
934 catch (const CORBA::Exception& ex)
936 ex._tao_print_exception ("Any performance test");
937 return 1;
940 return 0;