0023880: Integration of grid "ncl" into the new testing system
authorabv <abv@opencascade.com>
Thu, 29 Jan 2015 10:09:07 +0000 (13:09 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 29 Jan 2015 10:10:14 +0000 (13:10 +0300)
Function perf_sprint_all_meters added in OSD_PerfMeter.h to allow printing to string buffer rather than stdout. Macro PERF_PRINT_ALL converted to functional form.

Command dperf added in DRAW to print and conditionally reset all meters.
Description of these tools is added in Debug Hints.

Modified output of command QANTestNCollectionPerformance.
Added test case perf/ncollection/A1

Modified ratio of performance to check all platforms

Small correction of test-case for Windows platform

dox/dev_guides/debug/debug.md
src/Draw/Draw_BasicCommands.cxx
src/OSD/OSD_PerfMeter.cxx
src/OSD/OSD_PerfMeter.h
src/QANCollection/QANCollection_Perf.cxx
src/QANCollection/QANCollection_Simple.cxx
src/QANCollection/QANCollection_Stl.cxx
tests/perf/grids.list
tests/perf/ncollection/A1 [new file with mode: 0644]

index ceed13b..1f43b8f 100644 (file)
@@ -269,4 +269,21 @@ Handle_TCollection_HAsciiString {
 }
 ~~~~~
 
-In Visual Studio 2012 and later, visualizers can be put in a separate file in subdirectory *Visualizers*. See file *occt.natvis* for example.
\ No newline at end of file
+In Visual Studio 2012 and later, visualizers can be put in a separate file in subdirectory *Visualizers*. See file *occt.natvis* for example.
+
+@section occt_debug_perf Performance measurement tools
+
+It is recommended to use specialized performance analysis tools to profile OCCT and application code.
+However, when such tools are not available or cannot be used for some reason, tools provided by OCD package can be used: see low-level C functions and macros defined OSD_PerfMeter.h, and OSD_PerfMeter class.
+
+This tool maintains an array of 100 global performance counters that can be started and stopped independently.
+Adding performance counter to a function of interest allows to get statistics on number of calls and total execution time of the function.
+In C++ code, this can be achieved by creating local variable OSD_PerfMeter in each block of code to be measured.
+In C or Fortran code, use functions perf_start_meter and perf_stop_meter to start and stop the counter.
+Note that this instrumentation is intended to be removed when profiling is completed.
+Macros provided in OSD_PerfMeter.h can be used to keep instrumentation code permanently, but enable it only when macro PERF_ENABLE_METERS is defined.
+Each counter has its name shown when the collected statistics are printed.
+
+In DRAW, use command dperf to prints all performance statistics.
+
+Note that performance counters are not thread-safe.
index 6499309..500718a 100644 (file)
@@ -32,6 +32,7 @@
 #include <OSD_Chronometer.hxx>
 #include <OSD.hxx>
 #include <OSD_Exception_CTRL_BREAK.hxx>
+#include <OSD_PerfMeter.h>
 
 #ifdef _WIN32
 
@@ -722,6 +723,21 @@ static int dmeminfo (Draw_Interpretor& theDI,
 }
 
 //==============================================================================
+//function : dperf
+//purpose  :
+//==============================================================================
+
+static int dperf (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
+{
+  // reset if argument is provided and it is not '0'
+  int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0);
+  char buffer[25600];
+  perf_sprint_all_meters (buffer, 25600 - 1, reset);
+  theDI << buffer;
+  return 0;
+}
+
+//==============================================================================
 //function : dtracelevel
 //purpose  :
 //==============================================================================
@@ -843,6 +859,8 @@ void Draw::BasicCommands(Draw_Interpretor& theCommands)
     "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
     " : memory counters for this process",
          __FILE__, dmeminfo, g);
+  theCommands.Add("dperf","dperf [reset] -- show performance counters, reset if argument is provided",
+                 __FILE__,dperf,g);
 
   // Logging commands; note that their names are hard-coded in the code
   // of Draw_Interpretor, thus should not be changed without update of that code!
index 498f1b9..3c0fbe6 100644 (file)
@@ -218,18 +218,36 @@ int perf_get_meter (const char  * const MeterName,
 Function :      perf_print_all_meters
 Purpose  :      Prints on stdout the cumulated time and the number of
                 enters for each meter in MeterTable;
-                resets all meters
-Output   :      none
-Returns  :      none
+                resets all meters if reset is non-null
 ======================================================================*/
-void perf_print_all_meters (void)
+void perf_print_all_meters (int reset)
 {
+  char buffer[MAX_METERS * 256];
+  perf_sprint_all_meters (buffer, MAX_METERS * 256, reset);
+  printf ("%s", buffer);
+}
+
+/*======================================================================
+Function :      perf_print_all_meters
+Purpose  :      Prints to string buffer the cumulated time and the number of
+                enters for each meter in MeterTable;
+                resets all meters if reset is non-null
+======================================================================*/
+void perf_sprint_all_meters (char *buffer, int length, int reset)
+{
+  char string[256];
+
   int i;
   for (i=0; i<nb_meters; i++) {
     const t_TimeCounter * const ptc = &MeterTable[i];
     if (ptc && ptc->nb_enter) {
-      printf ("          Perf meter results               :"
-              "   enters  seconds  \xe6sec/enter\n");
+      int n = sprintf (string, "          Perf meter results               :   enters  seconds  sec/enter\n");
+      if (n < length)
+      {
+        memcpy (buffer, string, n);
+        buffer += n;
+        length -= n;
+      }
       break;
     }
   }
@@ -240,18 +258,29 @@ void perf_print_all_meters (void)
     if (ptc && ptc->nb_enter) {
       const double secs = ptc->cumul_time;
 
+      int n = 0;
       if (ptc->start_time)
-        printf ("Warning : meter %s has not been stopped\n", ptc->name);
-
-      printf ("%-42s : %7d %8.2f %10.2f\n",
-              ptc->name, ptc->nb_enter, secs,
-              (secs>0. ? 1000000 * secs/ptc->nb_enter : 0.));
-
-      ptc->cumul_time = 0;
-      ptc->start_time = 0;
-      ptc->nb_enter   = 0;
+        n = sprintf (string, "Warning : meter %42s has not been stopped\n", ptc->name);
+
+      n += sprintf (string + n, "%-42s : %7d %8.2f %10.2f\n",
+                    ptc->name, ptc->nb_enter, secs,
+                    (secs>0. ? 1000000 * secs/ptc->nb_enter : 0.));
+      if (n < length)
+      {
+        memcpy (buffer, string, n);
+        buffer += n;
+        length -= n;
+      }
+
+      if (reset)
+      {
+        ptc->cumul_time = 0;
+        ptc->start_time = 0;
+        ptc->nb_enter   = 0;
+      }
     }
   }
+  *buffer = '\0';
 }
 
 /*======================================================================
@@ -261,17 +290,7 @@ Returns  :      none
 ======================================================================*/
 void perf_close_meter (const char * const MeterName)
 {
-  const int ic = find_meter (MeterName);
-  if (ic >= 0 && MeterTable[ic].nb_enter) {
-    t_TimeCounter * const ptc = &MeterTable[ic];
-    if (ptc->start_time)
-      printf ("  ===> Warning : meter %s has not been stopped\n", ptc->name);
-    printf ("  ===> [%s] : %d enters, %9.3f seconds\n",
-            ptc->name, ptc->nb_enter, ptc->cumul_time);
-    ptc->cumul_time = 0;
-    ptc->start_time = 0;
-    ptc->nb_enter   = 0;
-  }
+  perf_close_imeter (find_meter (MeterName));
 }
 
 /*======================================================================
@@ -311,7 +330,7 @@ void perf_destroy_all_meters (void)
 
 void perf_print_and_destroy (void)
 {
-  perf_print_all_meters ();
+  perf_print_all_meters (0);
   perf_destroy_all_meters ();
 }
 
index a2a228d..d7feb91 100644 (file)
@@ -65,8 +65,8 @@
  * @def PERF_PRINT_ALL
  * Prints all existing meters which have been entered at least once and resets them.
  */
-#define PERF_PRINT_ALL { \
-  perf_print_all_meters(); \
+#define PERF_PRINT_ALL() { \
+  perf_print_all_meters(1); \
 }
 
 #else
@@ -74,7 +74,7 @@
   #define PERF_START_METER(_m_name)
   #define PERF_STOP_METER(_m_name)
   #define PERF_CLOSE_METER(_m_name)
-  #define PERF_PRINT_ALL
+  #define PERF_PRINT_ALL()
 #endif
 
 /**
@@ -143,9 +143,18 @@ Standard_EXPORTEXTERNC void perf_close_imeter (const int theMeterId);
 
 /**
  * Prints on stdout the cumulated time and the number of enters for each alive meter which have the number of enters > 0.
+ * Resets all meters if reset is non-null.
+ */
+Standard_EXPORTEXTERNC void perf_print_all_meters (int reset);
+
+/**
+ * Prints to supplied string buffer the cumulated time and the number of enters 
+ * for each alive meter with the number of enters > 0.
+ * If buffer length is not sufficient, data of some meters may be lost.
+ * It is recommended to reserve 256 bytes per meter, 25600 bytes should fit all.
  * Resets all meters.
  */
-Standard_EXPORTEXTERNC void perf_print_all_meters (void);
+Standard_EXPORTEXTERNC void perf_sprint_all_meters (char *buffer, int length, int reset);
 
 /**
  * Deletes all meters and frees memory.
@@ -154,7 +163,7 @@ Standard_EXPORTEXTERNC void perf_destroy_all_meters (void);
 
 /**
  * ATTENTION!!!
- * This func calls both perf_print_all_meters() and perf_destroy_all_meters()
+ * This func calls perf_print_all_meters() and perf_destroy_all_meters()
  * and is called automatically at the end of a program via system call atexit().
  */
 Standard_EXPORTEXTERNC void perf_print_and_destroy (void);
index c00d33c..a0fec09 100644 (file)
@@ -89,8 +89,16 @@ DEFINE_SEQUENCE(QANCollection_SequencePerf,QANCollection_BaseColPerf,ItemType)
 DEFINE_HSEQUENCE(QANCollection_HSequencePerf,QANCollection_SequencePerf)
 IMPLEMENT_HSEQUENCE(QANCollection_HSequencePerf)
 
+static void printAllMeters (Draw_Interpretor& theDI)
+{
+  char buffer[25600];
+  perf_sprint_all_meters (buffer, 25600 - 1, 1);
+  theDI << buffer;
+}
+
 // ===================== Test perform of Array1 type ==========================
-static void CompArray1 (const Standard_Integer theRep,
+static void CompArray1 (Draw_Interpretor& theDI,
+                        const Standard_Integer theRep,
                         const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -169,11 +177,12 @@ static void CompArray1 (const Standard_Integer theRep,
       ////////////////////////////////aTOper.Stop();
       PERF_STOP_METER("TCollection_Array1 operator=")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of Array2 type ==========================
-static void CompArray2 (const Standard_Integer theRep,
+static void CompArray2 (Draw_Interpretor& theDI,
+                        const Standard_Integer theRep,
                         const Standard_Integer theSize)
 {
   Standard_Integer i,j,k;
@@ -256,11 +265,12 @@ static void CompArray2 (const Standard_Integer theRep,
       ////////////////////////////////aTOper.Stop();
       PERF_STOP_METER("TCollection_Array2 operator=")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of List type ==========================
-static void CompList (const Standard_Integer theRep,
+static void CompList (Draw_Interpretor& theDI,
+                      const Standard_Integer theRep,
                       const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -327,11 +337,12 @@ static void CompList (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_List clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of Sequence type ==========================
-static void CompSequence (const Standard_Integer theRep,
+static void CompSequence (Draw_Interpretor& theDI,
+                          const Standard_Integer theRep,
                           const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -420,11 +431,12 @@ static void CompSequence (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_Sequence clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of Map type ==========================
-static void CompMap (const Standard_Integer theRep,
+static void CompMap (Draw_Interpretor& theDI,
+                     const Standard_Integer theRep,
                      const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -513,11 +525,12 @@ static void CompMap (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_Map clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of DataMap type ==========================
-static void CompDataMap (const Standard_Integer theRep,
+static void CompDataMap (Draw_Interpretor& theDI,
+                         const Standard_Integer theRep,
                          const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -608,11 +621,12 @@ static void CompDataMap (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_DataMap clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of DoubleMap type ==========================
-static void CompDoubleMap (const Standard_Integer theRep,
+static void CompDoubleMap (Draw_Interpretor& theDI,
+                           const Standard_Integer theRep,
                            const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -718,14 +732,15 @@ static void CompDoubleMap (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_DoubleMap clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
   if (iFail1 || iFail2)
     cout << "Warning : N map failed " << iFail1 << " times, T map - " << 
       iFail2 << endl;
 }
 
 // ===================== Test perform of IndexedMap type ==========================
-static void CompIndexedMap (const Standard_Integer theRep,
+static void CompIndexedMap (Draw_Interpretor& theDI,
+                            const Standard_Integer theRep,
                             const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -815,11 +830,12 @@ static void CompIndexedMap (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_IndexedMap clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of IndexedDataMap type ==========================
-static void CompIndexedDataMap (const Standard_Integer theRep,
+static void CompIndexedDataMap (Draw_Interpretor& theDI,
+                                const Standard_Integer theRep,
                                 const Standard_Integer theSize)
 {
   Standard_Integer i,j;
@@ -911,11 +927,13 @@ static void CompIndexedDataMap (const Standard_Integer theRep,
       ////////////////////////////////aTClea.Stop();
       PERF_STOP_METER("TCollection_IndexedDataMap clearing")
     }
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 // ===================== Test perform of SparseArray type ==========================
-static void CompSparseArray (const Standard_Integer theRep, const Standard_Integer theSize)
+static void CompSparseArray (Draw_Interpretor& theDI,
+                             const Standard_Integer theRep, 
+                             const Standard_Integer theSize)
 {
   Standard_Integer i,j;
   for (i=0; i<theRep; i++)
@@ -968,7 +986,7 @@ static void CompSparseArray (const Standard_Integer theRep, const Standard_Integ
       
     }
 
-  PERF_PRINT_ALL
+  printAllMeters(theDI);
 }
 
 //=======================================================================
@@ -1005,7 +1023,7 @@ static Standard_Integer QANColPerfArray1(Draw_Interpretor& di, Standard_Integer
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompArray1(Repeat,Size);
+  CompArray1 (di, Repeat, Size);
   return 0;
 }
 
@@ -1019,7 +1037,7 @@ static Standard_Integer QANColPerfArray2(Draw_Interpretor& di, Standard_Integer
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompArray2(Repeat,Size);
+  CompArray2 (di, Repeat, Size);
   return 0;
 }
 
@@ -1033,7 +1051,7 @@ static Standard_Integer QANColPerfList(Draw_Interpretor& di, Standard_Integer ar
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompList(Repeat,Size);
+  CompList (di, Repeat, Size);
   return 0;
 }
 
@@ -1047,7 +1065,7 @@ static Standard_Integer QANColPerfSequence(Draw_Interpretor& di, Standard_Intege
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompSequence(Repeat,Size);
+  CompSequence (di, Repeat, Size);
   return 0;
 }
 
@@ -1061,7 +1079,7 @@ static Standard_Integer QANColPerfMap(Draw_Interpretor& di, Standard_Integer arg
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompMap(Repeat,Size);
+  CompMap (di, Repeat, Size);
   return 0;
 }
 
@@ -1075,7 +1093,7 @@ static Standard_Integer QANColPerfDataMap(Draw_Interpretor& di, Standard_Integer
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompDataMap(Repeat,Size);
+  CompDataMap (di, Repeat, Size);
   return 0;
 }
 
@@ -1089,7 +1107,7 @@ static Standard_Integer QANColPerfDoubleMap(Draw_Interpretor& di, Standard_Integ
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompDoubleMap(Repeat,Size);
+  CompDoubleMap (di, Repeat, Size);
   return 0;
 }
 
@@ -1103,7 +1121,7 @@ static Standard_Integer QANColPerfIndexedMap(Draw_Interpretor& di, Standard_Inte
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompIndexedMap(Repeat,Size);
+  CompIndexedMap (di, Repeat, Size);
   return 0;
 }
 
@@ -1117,7 +1135,7 @@ static Standard_Integer QANColPerfIndexedDataMap(Draw_Interpretor& di, Standard_
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompIndexedDataMap(Repeat,Size);
+  CompIndexedDataMap (di, Repeat, Size);
   return 0;
 }
 
@@ -1131,7 +1149,7 @@ static Standard_Integer QANColCheckSparseArray(Draw_Interpretor& di, Standard_In
   if ( CheckArguments(di, argc, argv, Repeat, Size) ) {
     return 1;
   }
-  CompSparseArray(Repeat,Size);
+  CompSparseArray (di, Repeat, Size);
   return 0;
 }
 
index 13dfde7..d168a76 100644 (file)
@@ -30,9 +30,11 @@ typedef NCollection_Sequence<gp_Pnt> MySequence;
 
 const Standard_Integer REPEAT = 100;
 
-void printAllMeters ()
+static void printAllMeters (Draw_Interpretor& theDI)
 {
-  PERF_PRINT_ALL
+  char buffer[25600];
+  perf_sprint_all_meters (buffer, 25600 - 1, 1);
+  theDI << buffer;
 }
 
 static void createArray (TColgp_Array1OfPnt& anArrPnt)
@@ -132,7 +134,7 @@ static void assignArray (MyArray1& aDest, const MyArray1& aSrc)
   }
 }
 
-static void checkArray (const Standard_Boolean isNewColl)
+static void checkArray (Draw_Interpretor& theDI, const Standard_Boolean isNewColl)
 {
   if (isNewColl) {
     MyArray1 anArrPnt (1, 100000), anArrPnt1 (1, 100000);
@@ -144,10 +146,11 @@ static void checkArray (const Standard_Boolean isNewColl)
     createArray (anArrPnt);
     assignArray (anArrPnt1, anArrPnt);
   }
-  printAllMeters ();
+  printAllMeters (theDI);
 }
 
-static void checkSequence (const Standard_Boolean isNewColl,
+static void checkSequence (Draw_Interpretor& theDI, 
+                           const Standard_Boolean isNewColl,
                            const Standard_Boolean isIncr)
 {
   if (isNewColl) {
@@ -165,7 +168,7 @@ static void checkSequence (const Standard_Boolean isNewColl,
     createSequence (aSeqPnt);
     assignSequence (aSeqPnt1, aSeqPnt);
   }
-  printAllMeters ();
+  printAllMeters (theDI);
 }
 
 //=======================================================================
@@ -183,7 +186,7 @@ static Standard_Integer QANColCheckArray1(Draw_Interpretor& di, Standard_Integer
   if (argc > 1) {
     if (strcmp (argv[1], "-n") == 0) isNewColl = Standard_True;
   }
-  checkArray (isNewColl);
+  checkArray (di, isNewColl);
   return 0;
 }
 
@@ -207,7 +210,7 @@ static Standard_Integer QANColCheckSequence(Draw_Interpretor& di, Standard_Integ
       isIncr = Standard_True;
     }
   }
-  checkSequence (isNewColl, isIncr);
+  checkSequence (di, isNewColl, isIncr);
   return 0;
 }
 
index 248e8f9..3c1332b 100644 (file)
@@ -947,7 +947,7 @@ static Standard_Integer QANTestStlIterators (
 //purpose  :
 //=======================================================================
 template<class CollectionType, class StlType>
-void TestPerformanceRandomIterator()
+void TestPerformanceRandomIterator(Draw_Interpretor& di)
 {
   OSD_Timer aTimer;
 
@@ -986,12 +986,12 @@ void TestPerformanceRandomIterator()
 
     Standard_Real aOccTime = aTimer.ElapsedTime();
 
-    std::cout << aSize << "\t" << aStlTime << "\t" <<
-      aOccTime << "\t" << aOccTime / aStlTime << std::endl;
+    di << aSize << "\t" << aStlTime << "\t" <<
+      aOccTime << "\t" << aOccTime / aStlTime << "\n";
 
     // check that result is the same
     if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
-      std::cout << "Error: sequences are not the same at the end!" << std::endl;
+      di << "Error: sequences are not the same at the end!" << "\n";
 
     delete aVector;
     delete aCollec;
@@ -1003,7 +1003,7 @@ void TestPerformanceRandomIterator()
 //purpose  :
 //=======================================================================
 template<class CollectionType, class StlType>
-void TestPerformanceForwardIterator()
+void TestPerformanceForwardIterator(Draw_Interpretor& di)
 {
   OSD_Timer aTimer;
 
@@ -1038,12 +1038,12 @@ void TestPerformanceForwardIterator()
 
     Standard_Real aOccTime = aTimer.ElapsedTime();
 
-    std::cout << aSize << "\t" << aStlTime << "\t" <<
-      aOccTime << "\t" << aOccTime / aStlTime << std::endl;
+    di << aSize << "\t" << aStlTime << "\t" <<
+      aOccTime << "\t" << aOccTime / aStlTime << "\n";
 
     // check that result is the same
     if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
-      std::cout << "Error: sequences are not the same at the end!" << std::endl;
+      di << "Error: sequences are not the same at the end!" << "\n";
 
     delete aVector;
     delete aCollec;
@@ -1055,7 +1055,7 @@ void TestPerformanceForwardIterator()
 //purpose  :
 //=======================================================================
 template<class CollectionType, class StlType>
-void TestPerformanceBidirIterator()
+void TestPerformanceBidirIterator(Draw_Interpretor& di)
 {
   OSD_Timer aTimer;
 
@@ -1090,12 +1090,12 @@ void TestPerformanceBidirIterator()
 
     Standard_Real aOccTime = aTimer.ElapsedTime();
 
-    std::cout << aSize << "\t" << aStlTime << "\t" <<
-      aOccTime << "\t" << aOccTime / aStlTime << std::endl;
+    di << aSize << "\t" << aStlTime << "\t" <<
+      aOccTime << "\t" << aOccTime / aStlTime << "\n";
 
     // check that result is the same
     if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
-      std::cout << "Error: sequences are not the same at the end!" << std::endl;
+      di << "Error: sequences are not the same at the end!" << "\n";
 
     delete aVector;
     delete aCollec;
@@ -1107,7 +1107,7 @@ void TestPerformanceBidirIterator()
 //purpose  :
 //=======================================================================
 template<class CollectionType, class T>
-void TestPerformanceMapAccess()
+void TestPerformanceMapAccess(Draw_Interpretor& di)
 {
   OSD_Timer aTimer;
 
@@ -1166,8 +1166,8 @@ void TestPerformanceMapAccess()
 
     if (aResult)
     {
-      std::cout << aSize << "\t" << aStlTime << "\t" <<
-        aOccTime << "\t" << (aStlTime > 1e-16 ? aOccTime / aStlTime : -1) << std::endl;
+      di << aSize << "\t" << aStlTime << "\t" <<
+        aOccTime << "\t" << (aStlTime > 1e-16 ? aOccTime / aStlTime : -1) << "\n";
     }
 
     delete aCollec;
@@ -1178,42 +1178,37 @@ void TestPerformanceMapAccess()
 //function : QANTestNCollectionPerformance
 //purpose  :
 //=======================================================================
-static Standard_Integer QANTestNCollectionPerformance (
-  Draw_Interpretor& /*theInterpretor*/, Standard_Integer, const char**)
+static Standard_Integer QANTestNCollectionPerformance (Draw_Interpretor& di, Standard_Integer, const char**)
 {
-  std::cout.precision (8);
+  di << "Testing performance (Size | STL time | OCCT time | STL/OCCT boost)" << "\n";
 
-  std::cout << "Testing performance (Size | STL time | OCCT time | STL/OCCT boost)\n";
-
-  std::cout << std::endl << "std::vector vs NCollection_Array1 (sort):\n" << std::endl;
-  TestPerformanceRandomIterator<NCollection_Array1<double>, std::vector<double> >();
-
-  std::cout << std::endl << "std::vector vs NCollection_Vector (sort):\n" << std::endl;
-  TestPerformanceRandomIterator<NCollection_Vector<double>, std::vector<double> >();
-
-  std::cout << std::endl << "std::vector vs NCollection_Array1 (replace):\n" << std::endl;
-  TestPerformanceForwardIterator<NCollection_Array1<double>, std::vector<double> >();
-
-  std::cout << std::endl << "std::vector vs NCollection_Vector (replace):\n" << std::endl;
-  TestPerformanceForwardIterator<NCollection_Vector<double>, std::vector<double> >();
-
-  std::cout << std::endl << "std::list vs NCollection_List (replace):\n" << std::endl;
-  TestPerformanceForwardIterator<NCollection_List<double>, std::list<double> >();
-
-  std::cout << std::endl << "std::list vs NCollection_Sequence (replace):\n" << std::endl;
-  TestPerformanceForwardIterator<NCollection_Sequence<double>, std::list<double> >();
+  di << "\n" << "std::vector vs NCollection_Array1 (sort):" << "\n\n";
+  TestPerformanceRandomIterator<NCollection_Array1<double>, std::vector<double> >(di);
+  
+  di << "\n" << "std::vector vs NCollection_Vector (sort):" << "\n\n";
+  TestPerformanceRandomIterator<NCollection_Vector<double>, std::vector<double> >(di);
+  
+  di << "\n" << "std::vector vs NCollection_Array1 (replace):" << "\n\n";
+  TestPerformanceForwardIterator<NCollection_Array1<double>, std::vector<double> >(di);
+  
+  di << "\n" << "std::vector vs NCollection_Vector (replace):" << "\n\n";
+  TestPerformanceForwardIterator<NCollection_Vector<double>, std::vector<double> >(di);
 
-  std::cout << std::endl << "std::list vs NCollection_Sequence (reverse):\n" << std::endl;
-  TestPerformanceBidirIterator<NCollection_Sequence<double>, std::list<double> >();
+  di << "\n" << "std::list vs NCollection_List (replace):" << "\n\n";
+  TestPerformanceForwardIterator<NCollection_List<double>, std::list<double> >(di);
 
-  std::cout << std::endl << "std::set vs NCollection_Map (search):\n" << std::endl;
-  TestPerformanceMapAccess<NCollection_Map<int>, int>();
+  di << "\n" << "std::list vs NCollection_Sequence (replace):" << "\n\n";
+  TestPerformanceForwardIterator<NCollection_Sequence<double>, std::list<double> >(di);
 
-  std::cout << std::endl << "std::set vs NCollection_IndexedMap (search):\n" << std::endl;
-  TestPerformanceMapAccess<NCollection_IndexedMap<int>, int>();
+  di << "\n" << "std::list vs NCollection_Sequence (reverse):" << "\n\n";
+  TestPerformanceBidirIterator<NCollection_Sequence<double>, std::list<double> >(di);
 
-  std::cout.unsetf (std::ios::floatfield);
+  di << "\n" << "std::set vs NCollection_Map (search):" << "\n\n";
+  TestPerformanceMapAccess<NCollection_Map<int>, int>(di);
 
+  di << "\n" << "std::set vs NCollection_IndexedMap (search):" << "\n\n";
+  TestPerformanceMapAccess<NCollection_IndexedMap<int>, int>(di);
+  
   return 0;
 }
 
index e2ad5b9..a99041f 100644 (file)
@@ -16,3 +16,4 @@
 016 single_object_wireframe
 017 bspline
 018 bop
+019 ncollection
diff --git a/tests/perf/ncollection/A1 b/tests/perf/ncollection/A1
new file mode 100644 (file)
index 0000000..f7a8f29
--- /dev/null
@@ -0,0 +1,52 @@
+cpulimit 5000
+pload QAcommands
+
+set info [QANTestNCollectionPerformance]
+
+set values {}
+set keys {}
+unset -nocomplain std_cl occt_cl diff_cl
+foreach line [split $info "\n"] {
+  if { [regexp {(std::.*)} $line] } {
+    lappend keys $line
+    if {[info exists std_cl] && [info exists occt_cl] && [info exists diff_cl]} {
+      lappend values "$diff_cl"
+    }
+  }
+  regexp {\s*[-0-9*.+eE]+\s+([-0-9*.+eE]+)\s+([-0-9*.+eE]+)\s+([-0-9*.+eE]+)} $line dump std_cl occt_cl diff_cl
+}
+lappend values "$diff_cl"
+
+if { [string compare $tcl_platform(platform) "windows"] != 0 } {
+  set check_values  { 1.2363286058767904
+                      1.9537414143534
+                      1.2596260162601621
+                      2.8737043746844462
+                      1.2133020329576465
+                      1.2164522569168656
+                      1.2495457282327385
+                      0.10352433841051313
+                      0.45175659293697572
+                    }
+} else {
+  set check_values  { 1.383409071179103
+                      5.1472531605899908
+                      1.35719377028335395
+                      5.5309830187022213
+                      1.18734859347377246
+                      1.18885181806915312
+                      1.4285334583511072
+                      0.20619280354776386
+                      0.05983563611646603
+                    }
+}
+set index 0
+foreach key $keys {
+  set value [lindex $values $index]
+  if { $value > [lindex $check_values $index] } {
+    puts "Error: performance of $key become worse"
+  } else {
+    puts "OK: performance of $key is OK"
+  }
+  incr index
+}