Teuchos Package Browser (Single Doxygen Collection) Version of the Day
RCP_Performance_UnitTests.cpp
Go to the documentation of this file.
00001 /*
00002 // @HEADER
00003 // ***********************************************************************
00004 //
00005 //                    Teuchos: Common Tools Package
00006 //                 Copyright (2004) Sandia Corporation
00007 //
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 // @HEADER
00042 */
00043 
00044 #include "Teuchos_UnitTestHarness.hpp"
00045 #include "Teuchos_RCP.hpp"
00046 #include "Teuchos_TabularOutputter.hpp"
00047 
00048 #ifdef HAVE_TEUCHOS_BOOST
00049 #  include "boost/shared_ptr.hpp"
00050 #endif
00051 
00052 
00053 namespace {
00054 
00055 
00056 using Teuchos::null;
00057 using Teuchos::RCP;
00058 using Teuchos::rcp;
00059 using Teuchos::TabularOutputter;
00060 
00061 
00062 double relCpuSpeed = 1e-2;
00063 int maxArraySize = 10000;
00064 double maxRcpRawCreateDestroyRatio = 10.0;
00065 double maxRcpRawAdjustRefCountRatio = 100.0;
00066 double maxRcpSpAdjustRefCountRatio = 5.0;
00067 double maxRcpRawObjAccessRatio = 10.0;
00068 
00069 const int intPrec = 8;
00070 const int dblPrec = 6;
00071 
00072 
00073 TEUCHOS_STATIC_SETUP()
00074 {
00075   Teuchos::CommandLineProcessor &clp =
00076     Teuchos::UnitTestRepository::getCLP();
00077   clp.setOption(
00078     "rel-cpu-speed", &relCpuSpeed,
00079     "The relative speed of the CPU (higher means the machine runs faster)"
00080     );
00081   clp.setOption(
00082     "max-array-size", &maxArraySize,
00083     "The maximum size of the arrays created"
00084     );
00085   clp.setOption(
00086     "max-rcp-create-destroy-ratio", &maxRcpRawCreateDestroyRatio,
00087     "The ratio of the final CPU time ratio of creating and destroying"
00088     "std::vector<char>(size) objects wrapped in an RCP object versus"
00089     "using just raw new and delete."
00090     );
00091   clp.setOption(
00092     "max-rcp-raw-adjust-ref-count-ratio", &maxRcpRawAdjustRefCountRatio,
00093     "The ratio of the final CPU time ratio for adjusting the reference"
00094     "count of RCP objects versus a raw pointer."
00095     );
00096   clp.setOption(
00097     "max-rcp-sp-adjust-ref-count-ratio", &maxRcpSpAdjustRefCountRatio,
00098     "The ratio of the final CPU time ratio for adjusting the reference"
00099     "count of RCP objects versus boost::shared_ptr objects."
00100     );
00101   clp.setOption(
00102     "max-rcp-raw-obj-access-ratio", &maxRcpRawObjAccessRatio,
00103     "The ratio of the final CPU time ratio for accessing the object for RCP"
00104     "versus a raw pointer."
00105     );
00106 
00107 }
00108 
00109 
00110 template<typename T>
00111 struct DeleteDeleter {};
00112 
00113 
00114 TEUCHOS_UNIT_TEST( RCP, _sizeofObjects )
00115 {
00116   out << "\nPrinting the size the RCP and RCPNodeImpl objects ...\n";
00117   TEST_INEQUALITY_CONST(sizeof(bool), 0);
00118   TEST_INEQUALITY_CONST(sizeof(double), 0);
00119   TEST_INEQUALITY_CONST(sizeof(double*), 0);
00120   TEST_INEQUALITY_CONST(sizeof(std::vector<double>), 0);
00121   TEST_INEQUALITY_CONST(sizeof(Teuchos::RCPNode*), 0);
00122   TEST_INEQUALITY_CONST(sizeof(Teuchos::ERCPStrength), 0);
00123   TEST_INEQUALITY_CONST(sizeof(Teuchos::RCPNodeHandle), 0);
00124   TEST_INEQUALITY_CONST(sizeof(Teuchos::RCP<std::vector<double> >), 0);
00125   TEST_INEQUALITY_CONST(
00126     sizeof(Teuchos::RCPNodeTmpl<std::vector<double>,
00127       Teuchos::DeallocDelete<std::vector<double> > >),
00128     0);
00129 #ifdef HAVE_TEUCHOS_BOOST
00130   TEST_INEQUALITY_CONST(sizeof(boost::detail::shared_count), 0);
00131   TEST_INEQUALITY_CONST(sizeof(boost::shared_ptr<std::vector<double> >), 0);
00132   TEST_INEQUALITY_CONST(sizeof(boost::detail::sp_counted_impl_p<std::vector<double> >), 0);
00133   TEST_INEQUALITY_CONST(
00134     sizeof(boost::detail::sp_counted_impl_pd<std::vector<double>,
00135       DeleteDeleter<std::vector<double> > >),
00136     0);
00137 #endif
00138 }
00139 
00140 
00141 TEUCHOS_UNIT_TEST( RCP, createDestroyOverhead )
00142 {
00143 
00144   typedef Teuchos::TabularOutputter TO;
00145 
00146   const int maxLoopIters = 1000;
00147   const double relTestCost = 1e-3;
00148   const double numInnerLoops = relCpuSpeed / relTestCost;
00149 
00150   out << "\n"
00151       << "Messuring the overhead of creating and destorying objects of different sizes\n"
00152       << "using raw C++ pointers, shared_ptr, and using RCP.\n"
00153       << "\n"
00154       << "Number of loops = relCpuSpeed/relTestCost = "
00155       << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
00156       << "\n";
00157 
00158   TabularOutputter outputter(out);
00159   outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
00160   outputter.setFieldTypePrecision(TO::INT, intPrec);
00161 
00162   outputter.pushFieldSpec("obj size", TO::INT);
00163   outputter.pushFieldSpec("num loops", TO::INT);
00164   outputter.pushFieldSpec("raw", TO::DOUBLE);
00165 #ifdef HAVE_TEUCHOS_BOOST
00166   outputter.pushFieldSpec("shared_ptr", TO::DOUBLE);
00167 #endif
00168   outputter.pushFieldSpec("RCP", TO::DOUBLE);
00169 #ifdef HAVE_TEUCHOS_BOOST
00170   outputter.pushFieldSpec("shared_ptr/raw", TO::DOUBLE);
00171 #endif
00172   outputter.pushFieldSpec("RCP/raw", TO::DOUBLE);
00173 
00174   outputter.outputHeader();
00175 
00176   double finalRcpRawRatio = 100000.0;
00177 
00178   int arraySize = 1;
00179   for (int test_case_k = 0;
00180     test_case_k < maxLoopIters && arraySize <= maxArraySize;
00181     ++test_case_k
00182     )
00183   {
00184 
00185     // obj size
00186     outputter.outputField(arraySize);
00187 
00188     // num loops
00189     const int numActualLoops =
00190       TEUCHOS_MAX(
00191         static_cast<int>(
00192           (numInnerLoops / arraySize)
00193           * std::log(static_cast<double>(arraySize+1))
00194           ),
00195         1
00196         );
00197     outputter.outputField(numActualLoops);
00198 
00199     // raw
00200     {
00201       std::vector<std::vector<char>*> p_raw_vec(numActualLoops);
00202       int i = 0;
00203       TEUCHOS_START_PERF_OUTPUT_TIMER(outputter, numActualLoops)
00204       {
00205         p_raw_vec[i] = new std::vector<char>(arraySize, 1);
00206         delete p_raw_vec[i];
00207         ++i;
00208       }
00209     }
00210     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
00211     
00212 #ifdef HAVE_TEUCHOS_BOOST
00213     // shared_ptr
00214     {
00215       typedef boost::shared_ptr<std::vector<char> > shared_ptr_t;
00216       std::vector<shared_ptr_t > sp_vec(numActualLoops);
00217       int i = 0;
00218       TEUCHOS_START_PERF_OUTPUT_TIMER(outputter, numActualLoops)
00219       {
00220         sp_vec[i] = shared_ptr_t(new std::vector<char>(arraySize, 1));
00221         sp_vec[i].reset();
00222         ++i;
00223       }
00224     }
00225     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime);
00226 #endif
00227 
00228     // RCP
00229     {
00230       std::vector<RCP<std::vector<char> > > p_vec(numActualLoops);
00231       int i = 0;
00232       TEUCHOS_START_PERF_OUTPUT_TIMER(outputter, numActualLoops)
00233       {
00234         p_vec[i] = rcp(new std::vector<char>(arraySize, 1));
00235         p_vec[i] = null;
00236       }
00237     }
00238     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime);
00239 
00240 #ifdef HAVE_TEUCHOS_BOOST
00241     // shared_ptr/rawPtr
00242     const double spRatio = spTime / rawPtrTime;
00243     outputter.outputField(spRatio);
00244 #endif
00245 
00246     // RCP/rawPtr
00247     const double rcpRatio = rcpTime / rawPtrTime;
00248     outputter.outputField(rcpRatio);
00249 
00250     outputter.nextRow();
00251     
00252     arraySize *= 4;
00253     finalRcpRawRatio = TEUCHOS_MIN(rcpRatio, finalRcpRawRatio);
00254 
00255   }
00256 
00257   out << "\n";
00258   TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawCreateDestroyRatio );
00259   out << "\n";
00260 
00261 }
00262 
00263 
00264 TEUCHOS_UNIT_TEST( RCP, referenceCountManipulationOverhead )
00265 {
00266 
00267   typedef Teuchos::TabularOutputter TO;
00268 
00269   const double relTestCost = 5e-3;
00270   const int maxLoopIters = 1000;
00271   const double numInnerLoops = relCpuSpeed / relTestCost;
00272 
00273   out << "\n"
00274       << "Messuring the overhead of incrementing and deincrementing the reference count\n"
00275       << "comparing RCP to raw pointer and boost::shared_ptr.\n"
00276       << "\n";
00277 
00278   TabularOutputter outputter(out);
00279   outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
00280   outputter.setFieldTypePrecision(TO::INT, intPrec);
00281 
00282   outputter.pushFieldSpec("array dim", TO::INT);
00283   outputter.pushFieldSpec("num loops", TO::INT);
00284   outputter.pushFieldSpec("raw", TO::DOUBLE);
00285   outputter.pushFieldSpec("shared_ptr", TO::DOUBLE);
00286   outputter.pushFieldSpec("RCP", TO::DOUBLE);
00287   outputter.pushFieldSpec("RCP/raw", TO::DOUBLE);
00288   outputter.pushFieldSpec("RCP/shared_ptr", TO::DOUBLE);
00289 
00290   outputter.outputHeader();
00291 
00292   double finalRcpRawRatio = 100000.0;
00293   double finalRcpSpRatio = 100000.0;
00294   int arraySize = 64;
00295 
00296   for (
00297     int test_case_k = 0;
00298     test_case_k < maxLoopIters && arraySize <= maxArraySize;
00299     ++test_case_k
00300     )
00301   {
00302 
00303     // array dim
00304     outputter.outputField(arraySize);
00305 
00306     // num loops
00307     const int numActualLoops =
00308       TEUCHOS_MAX(
00309         static_cast<int>(
00310           (numInnerLoops / arraySize)
00311           * std::log(static_cast<double>(arraySize+1))
00312           ),
00313         1
00314         );
00315     outputter.outputField(numActualLoops);
00316 
00317     // raw
00318     {
00319       char dummy_char = 'n';
00320       std::vector<char*> p_raw_vec(arraySize);
00321       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00322       {
00323         for (int i=0; i < arraySize; ++i) {
00324           p_raw_vec[i] = &dummy_char;
00325         }
00326       }
00327     }
00328     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
00329     
00330 #ifdef HAVE_TEUCHOS_BOOST
00331     // shared_ptr
00332     {
00333       typedef boost::shared_ptr<char> shared_ptr_t;
00334       shared_ptr_t sp(new char('n'));
00335       std::vector<shared_ptr_t> sp_vec(arraySize);
00336       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00337       {
00338         for (int i=0; i < arraySize; ++i) {
00339           sp_vec[i] = sp;
00340         }
00341       }
00342     }
00343     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime);
00344 #else
00345     outputter.outputField("-");
00346 #endif
00347 
00348     // RCP
00349     {
00350       RCP<char> p(new char('n'));
00351       std::vector<RCP<char> > p_vec(arraySize);
00352       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00353       {
00354         for (int i=0; i < arraySize; ++i) {
00355           p_vec[i] = p;
00356           // NOTE: This assignment operation tests the copy constructor and
00357           // the swap function.  This calls both bind() and unbind()
00358           // underneath.
00359         }
00360       }
00361     }
00362     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime);
00363 
00364     // RCP/raw
00365     const double rcpRawRatio = rcpTime / rawPtrTime;
00366     finalRcpRawRatio = TEUCHOS_MIN(rcpRawRatio, finalRcpRawRatio);
00367     outputter.outputField(rcpRawRatio);
00368 
00369 #ifdef HAVE_TEUCHOS_BOOST
00370     // RCP/shared_ptr
00371     const double rcpSpRatio = rcpTime / spTime;
00372     finalRcpSpRatio = TEUCHOS_MIN(rcpSpRatio, finalRcpSpRatio);
00373     outputter.outputField(rcpSpRatio);
00374 #else
00375     outputter.outputField("-");
00376 #endif
00377 
00378     outputter.nextRow();
00379     
00380     arraySize *= 4;
00381 
00382   }
00383 
00384   out << "\n";
00385   TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawAdjustRefCountRatio );
00386 #ifdef HAVE_TEUCHOS_BOOST
00387   out << "\n";
00388   TEST_COMPARE( finalRcpSpRatio, <=, maxRcpSpAdjustRefCountRatio );
00389   out << "\n";
00390 #else
00391   (void)finalRcpSpRatio;
00392 #endif
00393   
00394 }
00395 
00396 
00397 TEUCHOS_UNIT_TEST( RCP, dereferenceOverhead )
00398 {
00399 
00400   typedef Teuchos::TabularOutputter TO;
00401 
00402   const double relTestCost = 1e-4;
00403   const int maxLoopIters = 1000;
00404   const double numInnerLoops = relCpuSpeed / relTestCost;
00405 
00406   out << "\n"
00407       << "Messuring the overhead of dereferencing RCP, shared_ptr and a raw pointer.\n"
00408       << "\n";
00409 
00410   TabularOutputter outputter(out);
00411   outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
00412   outputter.setFieldTypePrecision(TO::INT, intPrec);
00413 
00414   outputter.pushFieldSpec("array dim", TO::INT);
00415   outputter.pushFieldSpec("num loops", TO::INT);
00416   outputter.pushFieldSpec("raw", TO::DOUBLE);
00417   outputter.pushFieldSpec("shared_ptr", TO::DOUBLE);
00418   outputter.pushFieldSpec("RCP", TO::DOUBLE);
00419   outputter.pushFieldSpec("RCP/raw", TO::DOUBLE);
00420   outputter.pushFieldSpec("RCP/shared_ptr", TO::DOUBLE);
00421 
00422   outputter.outputHeader();
00423 
00424   double finalRcpRawRatio = 100000.0;
00425   int arraySize = 64;
00426   const int dummy_int_val = 1;
00427   int overall_dummy_int_out = 0;
00428   
00429 
00430   for (
00431     int test_case_k = 0;
00432     test_case_k < maxLoopIters && arraySize <= maxArraySize;
00433     ++test_case_k
00434     )
00435   {
00436 
00437     // array dim
00438     outputter.outputField(arraySize);
00439 
00440     // num loops
00441     const int numActualLoops =
00442       TEUCHOS_MAX(
00443         static_cast<int>(
00444           (numInnerLoops / arraySize)
00445           * std::log(static_cast<double>(arraySize+1))
00446           ),
00447         1
00448         );
00449     outputter.outputField(numActualLoops);
00450 
00451     int dummy_int_out = 0;
00452 
00453     // raw
00454     {
00455       int dummy_int = dummy_int_val;
00456       std::vector<int*> p_raw_vec(arraySize);
00457       for (int i=0; i < arraySize; ++i) {
00458         p_raw_vec[i] = &dummy_int;
00459       }
00460       dummy_int_out = 0;
00461       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00462       {
00463         for (int i=0; i < arraySize; ++i) {
00464           dummy_int_out += *p_raw_vec[i];
00465         }
00466       }
00467     }
00468     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
00469     overall_dummy_int_out += dummy_int_out;
00470     
00471     // shared_ptr
00472 #ifdef HAVE_TEUCHOS_BOOST
00473     {
00474       typedef boost::shared_ptr<int> shared_ptr_t;
00475       shared_ptr_t sp(new int(dummy_int_val));
00476       std::vector<shared_ptr_t> sp_vec(arraySize);
00477       for (int i=0; i < arraySize; ++i) {
00478         sp_vec[i] = sp;
00479       }
00480       dummy_int_out = 0;
00481       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00482       {
00483         for (int i=0; i < arraySize; ++i) {
00484           dummy_int_out += *sp_vec[i];
00485         }
00486       }
00487     }
00488     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime);
00489     overall_dummy_int_out += dummy_int_out;
00490 #else
00491     outputter.outputField("-");
00492 #endif
00493 
00494     // RCP
00495     {
00496       RCP<int> p(new int(dummy_int_val));
00497       std::vector<RCP<int> > p_vec(arraySize);
00498       for (int i=0; i < arraySize; ++i) {
00499         p_vec[i] = p;
00500       }
00501       dummy_int_out = 0;
00502       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00503       {
00504         for (int i=0; i < arraySize; ++i) {
00505           dummy_int_out += *p_vec[i];
00506         }
00507       }
00508     }
00509     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime);
00510     overall_dummy_int_out += dummy_int_out;
00511 
00512     // RCP/raw
00513     const double rcpRawRatio = rcpTime / rawPtrTime;
00514     finalRcpRawRatio = TEUCHOS_MIN(rcpRawRatio, finalRcpRawRatio);
00515     outputter.outputField(rcpRawRatio);
00516 
00517 #ifdef HAVE_TEUCHOS_BOOST
00518     // RCP/shared_ptr
00519     const double rcpSpRatio = rcpTime / spTime;
00520     outputter.outputField(rcpSpRatio);
00521 #else
00522     outputter.outputField("-");
00523 #endif
00524 
00525     outputter.nextRow();
00526     
00527     arraySize *= 4;
00528 
00529   }
00530 
00531   out << "\n";
00532   TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawObjAccessRatio );
00533   out << "\n";
00534 
00535   // This silly variable must be accumulated or compilers like MSVC++ will
00536   // optimize away the loops!
00537   if (overall_dummy_int_out == 0)
00538     success = false;
00539   
00540 }
00541 
00542 
00543 struct SomeStruct {
00544   SomeStruct(int member_in) : member(member_in) {}
00545   int member;
00546 };
00547 
00548 
00549 TEUCHOS_UNIT_TEST( RCP, memberAccessOverhead )
00550 {
00551 
00552   typedef Teuchos::TabularOutputter TO;
00553 
00554   const double relTestCost = 1e-4;
00555   const int maxLoopIters = 1000;
00556   const double numInnerLoops = relCpuSpeed / relTestCost;
00557 
00558   out << "\n"
00559       << "Messuring the overhead of dereferencing RCP, shared_ptr and a raw pointer.\n"
00560       << "\n";
00561 
00562   TabularOutputter outputter(out);
00563   outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
00564   outputter.setFieldTypePrecision(TO::INT, intPrec);
00565 
00566   outputter.pushFieldSpec("array dim", TO::INT);
00567   outputter.pushFieldSpec("num loops", TO::INT);
00568   outputter.pushFieldSpec("raw", TO::DOUBLE);
00569   outputter.pushFieldSpec("shared_ptr", TO::DOUBLE);
00570   outputter.pushFieldSpec("RCP", TO::DOUBLE);
00571   outputter.pushFieldSpec("RCP/raw", TO::DOUBLE);
00572   outputter.pushFieldSpec("RCP/shared_ptr", TO::DOUBLE);
00573 
00574   outputter.outputHeader();
00575 
00576   double finalRcpRawRatio = 100000.0;
00577   int arraySize = 64;
00578   const int dummy_int_val = 1;
00579   int overall_dummy_int_out = 0;
00580 
00581   for (
00582     int test_case_k = 0;
00583     test_case_k < maxLoopIters && arraySize <= maxArraySize;
00584     ++test_case_k
00585     )
00586   {
00587 
00588     // array dim
00589     outputter.outputField(arraySize);
00590 
00591     // num loops
00592     const int numActualLoops =
00593       TEUCHOS_MAX(
00594         static_cast<int>(
00595           (numInnerLoops / arraySize)
00596           * std::log(static_cast<double>(arraySize+1))
00597           ),
00598         1
00599         );
00600     outputter.outputField(numActualLoops);
00601 
00602     int dummy_int_out = 0;
00603 
00604     // raw
00605     {
00606       SomeStruct dummy_SomeStruct(dummy_int_val);
00607       std::vector<SomeStruct*> p_raw_vec(arraySize);
00608       for (int i=0; i < arraySize; ++i) {
00609         p_raw_vec[i] = &dummy_SomeStruct;
00610       }
00611       dummy_int_out = 0;
00612       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00613       {
00614         for (int i=0; i < arraySize; ++i) {
00615           dummy_int_out += p_raw_vec[i]->member;
00616         }
00617       }
00618     }
00619     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
00620     overall_dummy_int_out += dummy_int_out;
00621     
00622     // shared_ptr
00623 #ifdef HAVE_TEUCHOS_BOOST
00624     {
00625       typedef boost::shared_ptr<SomeStruct> shared_ptr_t;
00626       shared_ptr_t sp(new SomeStruct(dummy_int_val));
00627       std::vector<shared_ptr_t> sp_vec(arraySize);
00628       for (int i=0; i < arraySize; ++i) {
00629         sp_vec[i] = sp;
00630       }
00631       dummy_int_out = 0;
00632       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00633       {
00634         for (int i=0; i < arraySize; ++i) {
00635           dummy_int_out += sp_vec[i]->member;
00636         }
00637       }
00638     }
00639     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime);
00640     overall_dummy_int_out += dummy_int_out;
00641 #else
00642     outputter.outputField("-");
00643 #endif
00644 
00645     // RCP
00646     {
00647       RCP<SomeStruct> p(new SomeStruct(dummy_int_val));
00648       std::vector<RCP<SomeStruct> > p_vec(arraySize);
00649       for (int i=0; i < arraySize; ++i) {
00650         p_vec[i] = p;
00651       }
00652       dummy_int_out = 0;
00653       TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
00654       {
00655         for (int i=0; i < arraySize; ++i) {
00656           dummy_int_out += p_vec[i]->member;
00657         }
00658       }
00659     }
00660     TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime);
00661     overall_dummy_int_out += dummy_int_out;
00662 
00663     // RCP/raw
00664     const double rcpRawRatio = rcpTime / rawPtrTime;
00665     finalRcpRawRatio = TEUCHOS_MIN(rcpRawRatio, finalRcpRawRatio);
00666     outputter.outputField(rcpRawRatio);
00667 
00668 #ifdef HAVE_TEUCHOS_BOOST
00669     // RCP/shared_ptr
00670     const double rcpSpRatio = rcpTime / spTime;
00671     outputter.outputField(rcpSpRatio);
00672 #else
00673     outputter.outputField("-");
00674 #endif
00675 
00676     outputter.nextRow();
00677     
00678     arraySize *= 4;
00679 
00680   }
00681 
00682   out << "\n";
00683   TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawObjAccessRatio );
00684   out << "\n";
00685 
00686   // This silly variable must be accumulated or compilers like MSVC++ will
00687   // optimize away the loops!
00688   if (overall_dummy_int_out == 0)
00689     success = false;
00690   
00691 }
00692 
00693 
00694 
00695 
00696 
00697 
00698 
00699 } // namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines