]> OCCT Git - occt.git/commitdiff
Foundation Classes - Return value is overridden by OCCT #528
authorDmitrii Kulikov <164657232+AtheneNoctuaPt@users.noreply.github.com>
Thu, 15 May 2025 14:21:52 +0000 (15:21 +0100)
committerGitHub <noreply@github.com>
Thu, 15 May 2025 14:21:52 +0000 (15:21 +0100)
- Removed OSD_PerfMeter.h and integrated its functionality directly into OSD_PerfMeter.hxx.
- Updated OSD_PerfMeter to manage stopwatches through a singleton StopwatchStorage class.
- Enhanced meter initialization and management to support shared meters by name.
- Implemented methods for starting, stopping, and printing elapsed time for performance meters.
- Added OSD_PerfMeter_Test.cxx to implement unit tests for OSD_PerfMeter functionality.
- Test bug23237 is delete as it refers to removed code.

src/Draw/TKDraw/Draw/Draw_BasicCommands.cxx
src/Draw/TKQADraw/QABugs/QABugs_19.cxx
src/Draw/TKQADraw/QANCollection/QANCollection_Perf.cxx
src/FoundationClasses/TKernel/GTests/FILES.cmake
src/FoundationClasses/TKernel/GTests/OSD_PerfMeter_Test.cxx [new file with mode: 0644]
src/FoundationClasses/TKernel/OSD/FILES.cmake
src/FoundationClasses/TKernel/OSD/OSD_PerfMeter.cxx
src/FoundationClasses/TKernel/OSD/OSD_PerfMeter.h [deleted file]
src/FoundationClasses/TKernel/OSD/OSD_PerfMeter.hxx
tests/bugs/fclasses/bug23237 [deleted file]

index 1dafbc839f0e174cba974283cf488c9455612895..a34a144f83d9ecebc3bac983b91ef332b1b2bcc1 100644 (file)
@@ -28,6 +28,7 @@
 #include <OSD_MAllocHook.hxx>
 #include <OSD_MemInfo.hxx>
 #include <OSD_Parallel.hxx>
+#include <OSD_PerfMeter.hxx>
 #include <OSD_ThreadPool.hxx>
 #include <Standard_Macro.hxx>
 #include <Standard_SStream.hxx>
@@ -35,7 +36,6 @@
 #include <Standard_Version.hxx>
 #include <TCollection_AsciiString.hxx>
 
-#include <OSD_PerfMeter.h>
 #ifdef _WIN32
 
   #include <windows.h>
@@ -969,10 +969,14 @@ static int dparallel(Draw_Interpretor& theDI, Standard_Integer theArgNb, const c
 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;
+  int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0);
+  const TCollection_AsciiString anOutput = OSD_PerfMeter::PrintALL();
+  theDI << anOutput;
+  if (reset)
+  {
+    OSD_PerfMeter::ResetALL();
+  }
+
   return 0;
 }
 
index 5a2c21cd4ab83f29f7a8726df074d056a75675e3..e201cdee7c4cb61eb77977382963c2cc992e4e7c 100644 (file)
@@ -130,58 +130,6 @@ static Standard_Integer OCC23361(Draw_Interpretor& di,
   return 0;
 }
 
-static Standard_Integer OCC23237(Draw_Interpretor& di,
-                                 Standard_Integer /*argc*/,
-                                 const char** /*argv*/)
-{
-  OSD_PerfMeter aPM("TestMeter", 0);
-  OSD_Timer     aTM;
-
-  // run some operation in cycle for about 2 seconds to have good values of times to compare
-  int count = 0;
-  printf("OSD_PerfMeter test.\nRunning Boolean operation on solids in loop.\n");
-  for (; aTM.ElapsedTime() < 2.; count++)
-  {
-    aPM.Start();
-    aTM.Start();
-
-    // do some operation that will take considerable time compared with time of starting / stopping
-    // timers
-    BRepPrimAPI_MakeBox    aBox(10., 10., 10.);
-    BRepPrimAPI_MakeSphere aSphere(10.);
-    BRepAlgoAPI_Cut        aCutter(aBox.Shape(), aSphere.Shape());
-
-    aTM.Stop();
-    aPM.Stop();
-  }
-
-  int              aNbEnters          = 0;
-  Standard_Real    aPerfMeter_CPUtime = 0., aTimer_CPUTime = 0., aS;
-  Standard_Integer aM, aH;
-  aTM.Show(aS, aM, aH, aTimer_CPUTime);
-
-  perf_get_meter("TestMeter", &aNbEnters, &aPerfMeter_CPUtime);
-  perf_init_meter("TestMeter");
-
-  Standard_Real aTimeDiff = (fabs(aTimer_CPUTime - aPerfMeter_CPUtime) / aTimer_CPUTime);
-
-  printf("\nMeasurement results (%d cycles):\n", count);
-  printf("\nOSD_PerfMeter CPU time: %lf\nOSD_Timer CPU time: %lf\n",
-         aPerfMeter_CPUtime,
-         aTimer_CPUTime);
-  printf("Time delta is: %.3lf %%\n", aTimeDiff * 100);
-
-  if (aTimeDiff > 0.2)
-    di << "OCC23237: Error: too much difference between CPU and elapsed times";
-  else if (aNbEnters != count)
-    di << "OCC23237: Error: counter reported by PerfMeter (" << aNbEnters
-       << ") does not correspond to actual number of cycles";
-  else
-    di << "OCC23237: OK";
-
-  return 0;
-}
-
 class IncrementerDecrementer
 {
 public:
@@ -5462,7 +5410,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands)
 
   theCommands.Add("OCC230", "OCC230 TrimmedCurve Pnt2d Pnt2d", __FILE__, OCC230, group);
   theCommands.Add("OCC23361", "OCC23361", __FILE__, OCC23361, group);
-  theCommands.Add("OCC23237", "OCC23237", __FILE__, OCC23237, group);
   theCommands.Add("OCC22980", "OCC22980", __FILE__, OCC22980, group);
   theCommands.Add("OCC23595", "OCC23595", __FILE__, OCC23595, group);
   theCommands.Add("OCC22611", "OCC22611 string nb", __FILE__, OCC22611, group);
index 7aec417283a0d7acfcf09b33fa854d52c52f86ea..657b82489d0b04263ba2282cb16ef2cab2d25f20 100644 (file)
@@ -97,9 +97,9 @@ DEFINE_HSEQUENCE(QANCollection_HSequencePerf, QANCollection_SequencePerf)
 
 static void printAllMeters(Draw_Interpretor& theDI)
 {
-  char buffer[25600];
-  perf_sprint_all_meters(buffer, 25600 - 1, 1);
-  theDI << buffer;
+  const TCollection_AsciiString aStr = OSD_PerfMeter::PrintALL();
+  theDI << aStr << "\n";
+  OSD_PerfMeter::ResetALL();
 }
 
 // ===================== Test perform of Array1 type ==========================
@@ -109,79 +109,60 @@ static void CompArray1(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNCrea ("NCollection_Array1 creation",0);
-  ////////////////////////////////Perf_Meter aTCrea ("TCollection_Array1 creation",0);
-  ////////////////////////////////Perf_Meter aNFill ("NCollection_Array1 filling",0);
-  ////////////////////////////////Perf_Meter aTFill ("TCollection_Array1 filling",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_Array1 finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_Array1 finding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_Array1 operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_Array1 operator=",0);
-  ////////////////////////////////Perf_Meter aNAssi ("NCollection_Array1 Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////aNCrea.Start();
-    PERF_START_METER("NCollection_Array1 creation")
-    ////////////////////////////////QANCollection_Array1 a1(1,theSize), a2(1,theSize);
+    OSD_PerfMeter            aCreationMeter("NCollection_Array1 creation");
     QANCollection_Array1Perf a1(1, theSize), a2(1, theSize);
-    ////////////////////////////////aNCrea.Stop();
-    PERF_STOP_METER("NCollection_Array1 creation")
-    ////////////////////////////////aNFill.Start();
-    PERF_START_METER("NCollection_Array1 filling")
+    aCreationMeter.Stop();
+
+    OSD_PerfMeter aFillingMeter("NCollection_Array1 filling");
     for (j = 1; j <= theSize; j++)
       Random(a1(j));
-    ////////////////////////////////aNFill.Stop();
-    PERF_STOP_METER("NCollection_Array1 filling")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_Array1 finding")
+    aFillingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_Array1 finding");
     for (j = 1; j <= theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a1.Value(iIndex + 1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_Array1 finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_Array1 operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_Array1 operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_Array1 operator=")
-    ////////////////////////////////aNAssi.Start();
-    PERF_START_METER("NCollection_Array1 Assign")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aAssignFnMeter("NCollection_Array1 Assign");
     a2.Assign(a1);
-    ////////////////////////////////aNAssi.Stop();
-    PERF_STOP_METER("NCollection_Array1 Assign")
+    aAssignFnMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////aTCrea.Start();
-    PERF_START_METER("TCollection_Array1 creation")
+    OSD_PerfMeter      aCreationMeter("TCollection_Array1 creation");
     TColgp_Array1OfPnt a1(1, theSize), a2(1, theSize);
-    ////////////////////////////////aTCrea.Stop();
-    PERF_STOP_METER("TCollection_Array1 creation")
-    ////////////////////////////////aTFill.Start();
-    PERF_START_METER("TCollection_Array1 filling")
+    aCreationMeter.Stop();
+
+    OSD_PerfMeter aFillingMeter("TCollection_Array1 filling");
     for (j = 1; j <= theSize; j++)
+    {
       Random(a1(j));
-    ////////////////////////////////aTFill.Stop();
-    PERF_STOP_METER("TCollection_Array1 filling")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_Array1 finding")
+    }
+    aFillingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_Array1 finding");
     for (j = 1; j <= theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a1.Value(iIndex + 1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_Array1 finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_Array1 operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_Array1 operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_Array1 operator=")
+    aAssignOperMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -192,34 +173,19 @@ static void CompArray2(Draw_Interpretor&      theDI,
                        const Standard_Integer theSize)
 {
   Standard_Integer i, j, k;
-
-  ////////////////////////////////Perf_Meter aNCrea ("NCollection_Array2 creation",0);
-  ////////////////////////////////Perf_Meter aTCrea ("TCollection_Array2 creation",0);
-  ////////////////////////////////Perf_Meter aNFill ("NCollection_Array2 filling",0);
-  ////////////////////////////////Perf_Meter aTFill ("TCollection_Array2 filling",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_Array2 finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_Array2 finding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_Array2 operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_Array2 operator=",0);
-  ////////////////////////////////Perf_Meter aNAssi ("NCollection_Array2 Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////aNCrea.Start();
-    PERF_START_METER("NCollection_Array2 creation")
-    ////////////////////////////////QANCollection_Array2 a1(1,theSize,1,theSize),
-    /// a2(1,theSize,1,theSize);
+    OSD_PerfMeter            aCreationMeter("NCollection_Array2 creation");
     QANCollection_Array2Perf a1(1, theSize, 1, theSize), a2(1, theSize, 1, theSize);
-    ////////////////////////////////aNCrea.Stop();
-    PERF_STOP_METER("NCollection_Array2 creation")
-    ////////////////////////////////aNFill.Start();
-    PERF_START_METER("NCollection_Array2 filling")
+    aCreationMeter.Stop();
+
+    OSD_PerfMeter aFillingMeter("NCollection_Array2 filling");
     for (j = 1; j <= theSize; j++)
       for (k = 1; k <= theSize; k++)
         Random(a1(j, k));
-    ////////////////////////////////aNFill.Stop();
-    PERF_STOP_METER("NCollection_Array2 filling")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_Array2 finding")
+    aFillingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_Array2 finding");
     for (j = 1; j <= theSize * theSize; j++)
     {
       Standard_Integer m, n;
@@ -227,36 +193,30 @@ static void CompArray2(Draw_Interpretor&      theDI,
       Random(n, theSize);
       a1.Value(m + 1, n + 1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_Array2 finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_Array2 operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_Array2 operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_Array2 operator=")
-    ////////////////////////////////aNAssi.Start();
-    PERF_START_METER("NCollection_Array2 Assign")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aAssignFnMeter("NCollection_Array2 Assign");
     a2.Assign(a1);
-    ////////////////////////////////aNAssi.Stop();
-    PERF_STOP_METER("NCollection_Array2 Assign")
+    aAssignFnMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////aTCrea.Start();
-    PERF_START_METER("TCollection_Array2 creation")
+    OSD_PerfMeter      aCreationMeter("TCollection_Array2 creation");
     TColgp_Array2OfPnt a1(1, theSize, 1, theSize), a2(1, theSize, 1, theSize);
-    ////////////////////////////////aTCrea.Stop();
-    PERF_STOP_METER("TCollection_Array2 creation")
-    ////////////////////////////////aTFill.Start();
-    PERF_START_METER("TCollection_Array2 filling")
+    aCreationMeter.Stop();
+
+    OSD_PerfMeter aFillingMeter("TCollection_Array2 filling");
     for (j = 1; j <= theSize; j++)
       for (k = 1; k <= theSize; k++)
         Random(a1(j, k));
-    ////////////////////////////////aTFill.Stop();
-    PERF_STOP_METER("TCollection_Array2 filling")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_Array2 finding")
+    aFillingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_Array2 finding");
     for (j = 1; j <= theSize * theSize; j++)
     {
       Standard_Integer m, n;
@@ -264,13 +224,11 @@ static void CompArray2(Draw_Interpretor&      theDI,
       Random(n, theSize);
       a1.Value(m + 1, n + 1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_Array2 finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_Array2 operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_Array2 operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_Array2 operator=")
+    aAssignOperMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -282,67 +240,52 @@ static void CompList(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNAppe ("NCollection_List appending",0);
-  ////////////////////////////////Perf_Meter aTAppe ("TCollection_List appending",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_List operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_List operator=",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_List clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_List clearing",0);
-  ////////////////////////////////Perf_Meter aNAssi ("NCollection_List Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_List a1, a2;
     QANCollection_ListPerf a1, a2;
-    ////////////////////////////////aNAppe.Start();
-    PERF_START_METER("NCollection_List appending")
+
+    OSD_PerfMeter aAppendingMeter("NCollection_List appending");
     for (j = 1; j <= theSize; j++)
     {
       ItemType anItem;
       Random(anItem);
       a1.Append(anItem);
     }
-    ////////////////////////////////aNAppe.Stop();
-    PERF_STOP_METER("NCollection_List appending")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_List operator=")
+    aAppendingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_List operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_List operator=")
-    ////////////////////////////////aNAssi.Start();
-    PERF_START_METER("NCollection_List Assign")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aAssignFnMeter("NCollection_List Assign");
     a2.Assign(a1);
-    ////////////////////////////////aNAssi.Stop();
-    PERF_STOP_METER("NCollection_List Assign")
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_List clearing")
+    aAssignFnMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("NCollection_List clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_List clearing")
+    aClearingMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     QANCollection_ListOfPnt a1, a2;
-    ////////////////////////////////aTAppe.Start();
-    PERF_START_METER("TCollection_List appending")
+
+    OSD_PerfMeter aAppendingMeter("TCollection_List appending");
     for (j = 1; j <= theSize; j++)
     {
       ItemType anItem;
       Random(anItem);
       a1.Append(anItem);
     }
-    ////////////////////////////////aTAppe.Stop();
-    PERF_STOP_METER("TCollection_List appending")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_List operator=")
+    aAppendingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_List operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_List operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_List clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("TCollection_List clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_List clearing")
+    aClearMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -354,89 +297,70 @@ static void CompSequence(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNAppe ("NCollection_Sequence appending",0);
-  ////////////////////////////////Perf_Meter aTAppe ("TCollection_Sequence appending",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_Sequence finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_Sequence finding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_Sequence operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_Sequence operator=",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_Sequence clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_Sequence clearing",0);
-  ////////////////////////////////Perf_Meter aNAssi ("NCollection_Sequence Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_Sequence a1, a2;
     QANCollection_SequencePerf a1, a2;
-    ////////////////////////////////aNAppe.Start();
-    PERF_START_METER("NCollection_Sequence appending")
+
+    OSD_PerfMeter aAppendingMeter("NCollection_Sequence appending");
     for (j = 1; j <= theSize; j++)
     {
       ItemType anItem;
       Random(anItem);
       a1.Append(anItem);
     }
-    ////////////////////////////////aNAppe.Stop();
-    PERF_STOP_METER("NCollection_Sequence appending")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_Sequence finding")
+    aAppendingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_Sequence finding");
     for (j = 1; j <= theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a1.Value(iIndex + 1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_Sequence finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_Sequence operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_Sequence operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_Sequence operator=")
-    ////////////////////////////////aNAssi.Start();
-    PERF_START_METER("NCollection_Sequence Assign")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aAssignFnMeter("NCollection_Sequence Assign");
     a2.Assign(a1);
-    ////////////////////////////////aNAssi.Stop();
-    PERF_STOP_METER("NCollection_Sequence Assign")
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_Sequence clearing")
+    aAssignFnMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("NCollection_Sequence clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_Sequence clearing")
+    aClearingMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     TColgp_SequenceOfPnt a1, a2;
-    ////////////////////////////////aTAppe.Start();
-    PERF_START_METER("TCollection_Sequence appending")
+
+    OSD_PerfMeter aAppendingMeter("TCollection_Sequence appending");
     for (j = 1; j <= theSize; j++)
     {
       ItemType anItem;
       Random(anItem);
       a1.Append(anItem);
     }
-    ////////////////////////////////aTAppe.Stop();
-    PERF_STOP_METER("TCollection_Sequence appending")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_Sequence finding")
+    aAppendingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_Sequence finding");
     for (j = 1; j <= theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a1.Value(iIndex + 1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_Sequence finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_Sequence operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_Sequence operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_Sequence operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_Sequence clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("TCollection_Sequence clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_Sequence clearing")
+    aClearMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -448,89 +372,70 @@ static void CompMap(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNBind ("NCollection_Map adding",0);
-  ////////////////////////////////Perf_Meter aTBind ("TCollection_Map adding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_Map operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_Map operator=",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_Map finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_Map finding",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_Map clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_Map clearing",0);
-  ////////////////////////////////Perf_Meter aNAssi ("NCollection_Map Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_Map a1, a2;
     QANCollection_MapPerf a1, a2;
-    ////////////////////////////////aNBind.Start();
-    PERF_START_METER("NCollection_Map adding")
+
+    OSD_PerfMeter aAddingMeter("NCollection_Map adding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Add(aKey1);
     }
-    ////////////////////////////////aNBind.Stop();
-    PERF_STOP_METER("NCollection_Map adding")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_Map finding")
+    aAddingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_Map finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Contains(aKey1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_Map finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_Map operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_Map operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_Map operator=")
-    ////////////////////////////////aNAssi.Start();
-    PERF_START_METER("NCollection_Map Assign")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aAssignFnMeter("NCollection_Map Assign");
     a2.Assign(a1);
-    ////////////////////////////////aNAssi.Stop();
-    PERF_STOP_METER("NCollection_Map Assign")
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_Map clearing")
+    aAssignFnMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("NCollection_Map clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_Map clearing")
+    aClearingMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     TColStd_MapOfReal a1, a2;
-    ////////////////////////////////aTBind.Start();
-    PERF_START_METER("TCollection_Map adding")
+
+    OSD_PerfMeter aAddingMeter("TCollection_Map adding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Add(aKey1);
     }
-    ////////////////////////////////aTBind.Stop();
-    PERF_STOP_METER("TCollection_Map adding")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_Map finding")
+    aAddingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_Map finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Contains(aKey1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_Map finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_Map operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_Map operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_Map operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_Map clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("TCollection_Map clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_Map clearing")
+    aClearMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -542,21 +447,11 @@ static void CompDataMap(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNBind ("NCollection_DataMap binding",0);
-  ////////////////////////////////Perf_Meter aTBind ("TCollection_DataMap binding",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_DataMap finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_DataMap finding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_DataMap operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_DataMap operator=",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_DataMap clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_DataMap clearing",0);
-  //////////////////////////////////Perf_Meter aNAssi ("NCollection_DataMap Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_DataMap a1, a2;
     QANCollection_DataMapPerf a1, a2;
-    ////////////////////////////////aNBind.Start();
-    PERF_START_METER("NCollection_DataMap binding")
+
+    OSD_PerfMeter aBindingMeter("NCollection_DataMap binding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -565,38 +460,31 @@ static void CompDataMap(Draw_Interpretor&      theDI,
       Random(anItem);
       a1.Bind(aKey1, anItem);
     }
-    ////////////////////////////////aNBind.Stop();
-    PERF_STOP_METER("NCollection_DataMap binding")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_DataMap finding")
+    aBindingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_DataMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.IsBound(aKey1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_DataMap finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_DataMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_DataMap operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_DataMap operator=")
-    // aNAssi.Start();
-    // a2.Assign(a1);
-    // aNAssi.Stop();
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_DataMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("NCollection_DataMap clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_DataMap clearing")
+    aClearMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     QANCollection_DataMapOfRealPnt a1, a2;
-    ////////////////////////////////aTBind.Start();
-    PERF_START_METER("TCollection_DataMap binding")
+
+    OSD_PerfMeter aBindingMeter("TCollection_DataMap binding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -605,28 +493,24 @@ static void CompDataMap(Draw_Interpretor&      theDI,
       Random(anItem);
       a1.Bind(aKey1, anItem);
     }
-    ////////////////////////////////aTBind.Stop();
-    PERF_STOP_METER("TCollection_DataMap binding")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_DataMap finding")
+    aBindingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_DataMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.IsBound(aKey1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_DataMap finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_DataMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_DataMap operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_DataMap operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_DataMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("TCollection_DataMap clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_DataMap clearing")
+    aClearMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -639,21 +523,11 @@ static void CompDoubleMap(Draw_Interpretor&      theDI,
   Standard_Integer i, j;
   Standard_Integer iFail1 = 0, iFail2 = 0;
 
-  ////////////////////////////////Perf_Meter aNBind ("NCollection_DoubleMap binding",0);
-  ////////////////////////////////Perf_Meter aTBind ("TCollection_DoubleMap binding",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_DoubleMap finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_DoubleMap finding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_DoubleMap operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_DoubleMap operator=",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_DoubleMap clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_DoubleMap clearing",0);
-  //////////////////////////////////Perf_Meter aNAssi ("NCollection_DoubleMap Assign",0);
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_DoubleMap a1, a2;
     QANCollection_DoubleMapPerf a1, a2;
-    ////////////////////////////////aNBind.Start();
-    PERF_START_METER("NCollection_DoubleMap binding")
+
+    OSD_PerfMeter aBindingMeter("NCollection_DoubleMap binding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -667,10 +541,9 @@ static void CompDoubleMap(Draw_Interpretor&      theDI,
       iFail1--;
       a1.Bind(aKey1, aKey2);
     }
-    ////////////////////////////////aNBind.Stop();
-    PERF_STOP_METER("NCollection_DoubleMap binding")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_DoubleMap finding")
+    aBindingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_DoubleMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -679,28 +552,22 @@ static void CompDoubleMap(Draw_Interpretor&      theDI,
       Random(aKey2);
       a1.AreBound(aKey1, aKey2);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_DoubleMap finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_DoubleMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_DoubleMap operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_DoubleMap operator=")
-    // aNAssi.Start();
-    // a2.Assign(a1);
-    // aNAssi.Stop();
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_DoubleMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("NCollection_DoubleMap clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_DoubleMap clearing")
+    aClearMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     QANCollection_DoubleMapOfRealInteger a1, a2;
-    ////////////////////////////////aTBind.Start();
-    PERF_START_METER("TCollection_DoubleMap binding")
+
+    OSD_PerfMeter aBindingMeter("TCollection_DoubleMap binding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -714,10 +581,9 @@ static void CompDoubleMap(Draw_Interpretor&      theDI,
       iFail2--;
       a1.Bind(aKey1, aKey2);
     }
-    ////////////////////////////////aTBind.Stop();
-    PERF_STOP_METER("TCollection_DoubleMap binding")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_DoubleMap finding")
+    aBindingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_DoubleMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -726,18 +592,15 @@ static void CompDoubleMap(Draw_Interpretor&      theDI,
       Random(aKey2);
       a1.AreBound(aKey1, aKey2);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_DoubleMap finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_DoubleMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_DoubleMap operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_DoubleMap operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_DoubleMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearMeter("TCollection_DoubleMap clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_DoubleMap clearing")
+    aClearMeter.Stop();
   }
   printAllMeters(theDI);
   if (iFail1 || iFail2)
@@ -751,90 +614,70 @@ static void CompIndexedMap(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNBind ("NCollection_IndexedMap adding",0);
-  ////////////////////////////////Perf_Meter aTBind ("TCollection_IndexedMap adding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_IndexedMap operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_IndexedMap operator=",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_IndexedMap finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_IndexedMap finding",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_IndexedMap clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_IndexedMap clearing",0);
-  ////////////////////////////////Perf_Meter aNAssi ("NCollection_IndexedMap Assign",0);
-
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_IndexedMap a1, a2;
     QANCollection_IndexedMapPerf a1, a2;
-    ////////////////////////////////aNBind.Start();
-    PERF_START_METER("NCollection_IndexedMap adding")
+
+    OSD_PerfMeter aAddingMeter("NCollection_IndexedMap adding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Add(aKey1);
     }
-    ////////////////////////////////aNBind.Stop();
-    PERF_STOP_METER("NCollection_IndexedMap adding")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_IndexedMap finding")
+    aAddingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_IndexedMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Contains(aKey1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_IndexedMap finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_IndexedMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_IndexedMap operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_IndexedMap operator=")
-    ////////////////////////////////aNAssi.Start();
-    PERF_START_METER("NCollection_IndexedMap Assign")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aAssignFnMeter("NCollection_IndexedMap Assign");
     a2.Assign(a1);
-    ////////////////////////////////aNAssi.Stop();
-    PERF_STOP_METER("NCollection_IndexedMap Assign")
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_IndexedMap clearing")
+    aAssignFnMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("NCollection_IndexedMap clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_IndexedMap clearing")
+    aClearingMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     TColStd_IndexedMapOfReal a1, a2;
-    ////////////////////////////////aTBind.Start();
-    PERF_START_METER("TCollection_IndexedMap adding")
+
+    OSD_PerfMeter aAddingMeter("TCollection_IndexedMap adding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Add(aKey1);
     }
-    ////////////////////////////////aTBind.Stop();
-    PERF_STOP_METER("TCollection_IndexedMap adding")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_IndexedMap finding")
+    aAddingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_IndexedMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Contains(aKey1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_IndexedMap finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_IndexedMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_IndexedMap operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_IndexedMap operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_IndexedMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("TCollection_IndexedMap clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_IndexedMap clearing")
+    aClearingMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -846,22 +689,12 @@ static void CompIndexedDataMap(Draw_Interpretor&      theDI,
 {
   Standard_Integer i, j;
 
-  ////////////////////////////////Perf_Meter aNBind ("NCollection_IndexedDataMap binding",0);
-  ////////////////////////////////Perf_Meter aTBind ("TCollection_IndexedDataMap binding",0);
-  ////////////////////////////////Perf_Meter aNFind ("NCollection_IndexedDataMap finding",0);
-  ////////////////////////////////Perf_Meter aTFind ("TCollection_IndexedDataMap finding",0);
-  ////////////////////////////////Perf_Meter aNOper ("NCollection_IndexedDataMap operator=",0);
-  ////////////////////////////////Perf_Meter aTOper ("TCollection_IndexedDataMap operator=",0);
-  ////////////////////////////////Perf_Meter aNClea ("NCollection_IndexedDataMap clearing",0);
-  ////////////////////////////////Perf_Meter aTClea ("TCollection_IndexedDataMap clearing",0);
-  //////////////////////////////////Perf_Meter aNAssi ("NCollection_IndexedDataMap Assign",0);
-
   for (i = 0; i < theRep; i++)
   {
-    ////////////////////////////////QANCollection_IDMap a1, a2;
+
     QANCollection_IDMapPerf a1, a2;
-    ////////////////////////////////aNBind.Start();
-    PERF_START_METER("NCollection_IndexedDataMap binding")
+
+    OSD_PerfMeter aBindingMeter("NCollection_IndexedDataMap binding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -870,38 +703,31 @@ static void CompIndexedDataMap(Draw_Interpretor&      theDI,
       Random(anItem);
       a1.Add(aKey1, anItem);
     }
-    ////////////////////////////////aNBind.Stop();
-    PERF_STOP_METER("NCollection_IndexedDataMap binding")
-    ////////////////////////////////aNFind.Start();
-    PERF_START_METER("NCollection_IndexedDataMap finding")
+    aBindingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("NCollection_IndexedDataMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Contains(aKey1);
     }
-    ////////////////////////////////aNFind.Stop();
-    PERF_STOP_METER("NCollection_IndexedDataMap finding")
-    ////////////////////////////////aNOper.Start();
-    PERF_START_METER("NCollection_IndexedDataMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("NCollection_IndexedDataMap operator=");
     a2 = a1;
-    ////////////////////////////////aNOper.Stop();
-    PERF_STOP_METER("NCollection_IndexedDataMap operator=")
-    // aNAssi.Start();
-    // a2.Assign(a1);
-    // aNAssi.Stop();
-    ////////////////////////////////aNClea.Start();
-    PERF_START_METER("NCollection_IndexedDataMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("NCollection_IndexedDataMap clearing");
     a2.Clear();
-    ////////////////////////////////aNClea.Stop();
-    PERF_STOP_METER("NCollection_IndexedDataMap clearing")
+    aClearingMeter.Stop();
   }
 
   for (i = 0; i < theRep; i++)
   {
     QANCollection_IndexedDataMapOfRealPnt a1, a2;
-    ////////////////////////////////aTBind.Start();
-    PERF_START_METER("TCollection_IndexedDataMap binding")
+
+    OSD_PerfMeter aBindingMeter("TCollection_IndexedDataMap binding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
@@ -910,28 +736,24 @@ static void CompIndexedDataMap(Draw_Interpretor&      theDI,
       Random(anItem);
       a1.Add(aKey1, anItem);
     }
-    ////////////////////////////////aTBind.Stop();
-    PERF_STOP_METER("TCollection_IndexedDataMap binding")
-    ////////////////////////////////aTFind.Start();
-    PERF_START_METER("TCollection_IndexedDataMap finding")
+    aBindingMeter.Stop();
+
+    OSD_PerfMeter aFindingMeter("TCollection_IndexedDataMap finding");
     for (j = 1; j <= theSize; j++)
     {
       Key1Type aKey1;
       Random(aKey1);
       a1.Contains(aKey1);
     }
-    ////////////////////////////////aTFind.Stop();
-    PERF_STOP_METER("TCollection_IndexedDataMap finding")
-    ////////////////////////////////aTOper.Start();
-    PERF_START_METER("TCollection_IndexedDataMap operator=")
+    aFindingMeter.Stop();
+
+    OSD_PerfMeter aAssignOperMeter("TCollection_IndexedDataMap operator=");
     a2 = a1;
-    ////////////////////////////////aTOper.Stop();
-    PERF_STOP_METER("TCollection_IndexedDataMap operator=")
-    ////////////////////////////////aTClea.Start();
-    PERF_START_METER("TCollection_IndexedDataMap clearing")
+    aAssignOperMeter.Stop();
+
+    OSD_PerfMeter aClearingMeter("TCollection_IndexedDataMap clearing");
     a2.Clear();
-    ////////////////////////////////aTClea.Stop();
-    PERF_STOP_METER("TCollection_IndexedDataMap clearing")
+    aClearingMeter.Stop();
   }
   printAllMeters(theDI);
 }
@@ -944,51 +766,50 @@ static void CompSparseArray(Draw_Interpretor&      theDI,
   Standard_Integer i, j;
   for (i = 0; i < theRep; i++)
   {
-    PERF_START_METER("NCollection_SparseArray creation")
-
+    OSD_PerfMeter                             aCreationMeter("NCollection_SparseArray creation");
     NCollection_SparseArray<Standard_Integer> a1(theSize), a2(theSize);
+    aCreationMeter.Stop();
 
-    PERF_STOP_METER("NCollection_SparseArray creation")
-
-    PERF_START_METER("NCollection_SparseArray filling")
+    OSD_PerfMeter aFillingMeter("NCollection_SparseArray filling");
     for (j = 0; j < theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a1.SetValue(j, iIndex + 1);
     }
+    aFillingMeter.Stop();
 
-    PERF_STOP_METER("NCollection_SparseArray filling")
-
-    PERF_START_METER("NCollection_SparseArray size")
+    OSD_PerfMeter aSizeMeter("NCollection_SparseArray size");
     Standard_Size sizeSparseArray = a1.Size();
     (void)sizeSparseArray; // avoid compiler warning on unused variable
-    PERF_STOP_METER("NCollection_SparseArray size")
+    aSizeMeter.Stop();
 
-    PERF_START_METER("NCollection_Array1 Assign")
+    OSD_PerfMeter aAssignFnMeter("NCollection_SparseArray Assign");
     a2.Assign(a1);
-    PERF_STOP_METER("NCollection_Array1 Assign")
-    PERF_START_METER("NCollection_SparseArray HasValue")
+    aAssignFnMeter.Stop();
+
+    OSD_PerfMeter aHasValueMeter("NCollection_SparseArray HasValue");
     for (j = 0; j < theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a2.HasValue(iIndex + 1);
     }
-    PERF_STOP_METER("NCollection_SparseArray HasValue")
-    PERF_START_METER("NCollection_SparseArray UnsetValue")
+    aHasValueMeter.Stop();
+
+    OSD_PerfMeter aUnsetValueMeter("NCollection_SparseArray UnsetValue");
     for (j = 0; j < theSize; j++)
     {
       Standard_Integer iIndex;
       Random(iIndex, theSize);
       a1.UnsetValue(iIndex + 1);
     }
-    PERF_STOP_METER("NCollection_SparseArray UnsetValue")
+    aUnsetValueMeter.Stop();
 
-    PERF_START_METER("NCollection_SparseArray Clear")
+    OSD_PerfMeter aClearMeter("NCollection_SparseArray Clear");
     a1.Clear();
     a2.Clear();
-    PERF_STOP_METER("NCollection_SparseArray Clear")
+    aClearMeter.Stop();
   }
 
   printAllMeters(theDI);
index 04eec737552e6c68f2e5c520afbca4d2f38c52f5..e11faf7f6f9e37ce751c530cfcf38213681420e6 100644 (file)
@@ -14,6 +14,7 @@ set(OCCT_TKernel_GTests_FILES
   NCollection_Sequence_Test.cxx
   NCollection_SparseArray_Test.cxx
   NCollection_Vector_Test.cxx
+  OSD_PerfMeter_Test.cxx
   TCollection_AsciiString_Test.cxx
   TCollection_ExtendedString_Test.cxx
 )
diff --git a/src/FoundationClasses/TKernel/GTests/OSD_PerfMeter_Test.cxx b/src/FoundationClasses/TKernel/GTests/OSD_PerfMeter_Test.cxx
new file mode 100644 (file)
index 0000000..8531e97
--- /dev/null
@@ -0,0 +1,357 @@
+#include <gtest/gtest.h>
+#include <OSD_PerfMeter.hxx>
+
+#include <BRepPrimAPI_MakeBox.hxx>
+#include <BRepPrimAPI_MakeSphere.hxx>
+#include <BRepAlgoAPI_Cut.hxx>
+
+#include <chrono>
+#include <thread>
+#include <sstream>
+#include <string>
+#include <vector>
+
+// Test fixture for OSD_PerfMeter tests
+class OSD_PerfMeterTest : public ::testing::Test
+{
+protected:
+  void SetUp() override
+  {
+    // Reset all meters before each test
+    OSD_PerfMeter::ResetALL();
+  }
+
+  void TearDown() override
+  {
+    // Reset all meters after each test
+    OSD_PerfMeter::ResetALL();
+  }
+
+  // Helper function to perform some measurable work
+  static void DoSomeWork(const double theTimeInSec = 0.1)
+  {
+    OSD_PerfMeter meter("WorkMeter", true);
+    while (meter.Elapsed() < theTimeInSec)
+    {
+      // do some operation that will take considerable time compared with time of starting /
+      // stopping timers
+      BRepPrimAPI_MakeBox    aBox(10., 10., 10.);
+      BRepPrimAPI_MakeSphere aSphere(10.);
+      BRepAlgoAPI_Cut        aCutter(aBox.Shape(), aSphere.Shape());
+    }
+    meter.Kill();
+  }
+};
+
+//==================================================================================================
+
+// Test basic creation and auto-start functionality
+TEST_F(OSD_PerfMeterTest, BasicCreationWithAutoStart)
+{
+  // Create an auto-started meter
+  OSD_PerfMeter meter("TestMeter", true);
+
+  // Do some work
+  DoSomeWork();
+
+  // Stop the meter
+  meter.Stop();
+
+  // Check elapsed time is positive
+  double elapsed = meter.Elapsed();
+  EXPECT_GT(elapsed, 0.0) << "Elapsed time should be positive";
+}
+
+//==================================================================================================
+
+// Test manual start/stop functionality
+TEST_F(OSD_PerfMeterTest, ManualStartStop)
+{
+  // Create a meter without auto-start
+  OSD_PerfMeter meter("ManualMeter", false);
+
+  // Start the meter
+  meter.Start();
+
+  // Do some work
+  DoSomeWork();
+
+  // Stop the meter
+  meter.Stop();
+
+  // Check elapsed time is positive
+  double elapsed = meter.Elapsed();
+  EXPECT_GT(elapsed, 0.0) << "Elapsed time should be positive";
+}
+
+//==================================================================================================
+
+// Test default constructor and Init
+TEST_F(OSD_PerfMeterTest, DefaultConstructorAndInit)
+{
+  // Create meter with default constructor
+  OSD_PerfMeter meter;
+
+  // Initialize it
+  meter.Init("InitializedMeter");
+
+  // Start it manually
+  meter.Start();
+
+  // Do some work
+  DoSomeWork();
+
+  // Stop and check elapsed time
+  meter.Stop();
+  EXPECT_GT(meter.Elapsed(), 0.0) << "Initialized meter should have positive elapsed time";
+}
+
+//==================================================================================================
+
+// Test that two meters with the same name refer to the same internal meter
+TEST_F(OSD_PerfMeterTest, SharedMetersByName)
+{
+  const char* meterName = "SharedMeter";
+
+  // Create and start first meter
+  OSD_PerfMeter meter1(meterName);
+
+  // Do some work
+  DoSomeWork();
+
+  // Create second meter with the same name, but don't auto-start
+  OSD_PerfMeter meter2;
+  meter2.Init(meterName);
+
+  // Do more work
+  DoSomeWork();
+
+  // Stop both meters
+  meter1.Stop();
+
+  // The elapsed time should account for both work segments
+  double elapsed = meter1.Elapsed();
+  EXPECT_GT(elapsed, 0.0) << "Elapsed time should be positive";
+
+  // Stopping meter2 should have no effect since they share the same meter
+  // and meter1 already stopped it
+  meter2.Stop();
+  double elapsed2 = meter2.Elapsed();
+  EXPECT_DOUBLE_EQ(elapsed, elapsed2) << "Both meter instances should show same elapsed time";
+}
+
+//==================================================================================================
+
+// Test restarting a meter
+TEST_F(OSD_PerfMeterTest, RestartMeter)
+{
+  // Create and start meter
+  OSD_PerfMeter meter("RestartMeter");
+
+  // Do some work
+  DoSomeWork(0.1);
+
+  // Stop and get elapsed time
+  meter.Stop();
+  double elapsed1 = meter.Elapsed();
+  EXPECT_GT(elapsed1, 0.0) << "First elapsed time should be positive";
+
+  // Restart the meter
+  meter.Start();
+
+  // Do more work
+  DoSomeWork(0.2);
+
+  // Stop and get elapsed time again
+  meter.Stop();
+  double elapsed2 = meter.Elapsed();
+  EXPECT_GT(elapsed2, 0.0) << "Second elapsed time should be positive";
+
+  // Second elapsed time should be different from first
+  EXPECT_NE(elapsed1, elapsed2) << "After restart, elapsed time should be different";
+}
+
+//==================================================================================================
+
+// Test relative timing accuracy
+TEST_F(OSD_PerfMeterTest, RelativeTimingAccuracy)
+{
+  // Create two meters
+  OSD_PerfMeter meter1("ShortMeter");
+  OSD_PerfMeter meter2("LongMeter");
+
+  // Short work for meter1
+  DoSomeWork(0.1);
+  meter1.Stop();
+
+  // Long work for meter2
+  DoSomeWork(0.5);
+  meter2.Stop();
+
+  // Long work should take more time than short work
+  double shortElapsed = meter1.Elapsed();
+  double longElapsed  = meter2.Elapsed();
+
+  EXPECT_GT(shortElapsed, 0.0) << "Short elapsed time should be positive";
+  EXPECT_GT(longElapsed, 0.0) << "Long elapsed time should be positive";
+  EXPECT_GT(longElapsed, shortElapsed) << "Long work should take more time than short work";
+}
+
+//==================================================================================================
+
+// Test the static PrintALL method
+TEST_F(OSD_PerfMeterTest, PrintALL)
+{
+  // Create and use several meters
+  OSD_PerfMeter meter1("Meter1");
+  DoSomeWork(0.1);
+  meter1.Stop();
+
+  OSD_PerfMeter meter2("Meter2");
+  DoSomeWork(0.2);
+  meter2.Stop();
+
+  OSD_PerfMeter meter3("Meter3");
+  DoSomeWork(0.3);
+  meter3.Stop();
+
+  // Get the printed output
+  std::string output = OSD_PerfMeter::PrintALL().ToCString();
+
+  // Check that the output contains all meter names
+  EXPECT_TRUE(output.find("Meter1") != std::string::npos)
+    << "PrintALL output should contain Meter1";
+  EXPECT_TRUE(output.find("Meter2") != std::string::npos)
+    << "PrintALL output should contain Meter2";
+  EXPECT_TRUE(output.find("Meter3") != std::string::npos)
+    << "PrintALL output should contain Meter3";
+}
+
+//==================================================================================================
+
+// Test the static ResetALL method
+TEST_F(OSD_PerfMeterTest, ResetALL)
+{
+  // Create and use several meters
+  OSD_PerfMeter meter1("ResetMeter1");
+  DoSomeWork(0.1);
+  meter1.Stop();
+
+  OSD_PerfMeter meter2("ResetMeter2");
+  DoSomeWork(0.2);
+  meter2.Stop();
+
+  // Both meters should have positive elapsed times
+  EXPECT_GT(meter1.Elapsed(), 0.0);
+  EXPECT_GT(meter2.Elapsed(), 0.0);
+
+  // Reset all meters
+  OSD_PerfMeter::ResetALL();
+
+  // After reset, all meters should have zero elapsed time
+  EXPECT_EQ(meter1.Elapsed(), 0.0) << "Elapsed time should be zero after ResetALL";
+  EXPECT_EQ(meter2.Elapsed(), 0.0) << "Elapsed time should be zero after ResetALL";
+}
+
+//==================================================================================================
+
+// Test unused meter behavior
+TEST_F(OSD_PerfMeterTest, UnusedMeter)
+{
+  // Create a meter but don't start it
+  OSD_PerfMeter meter("UnusedMeter", false);
+
+  // Elapsed time should be zero
+  EXPECT_EQ(meter.Elapsed(), 0.0) << "Unused meter should have zero elapsed time, actual";
+
+  // Stopping not started meter should have no effect
+  meter.Stop();
+  EXPECT_EQ(meter.Elapsed(), 0.0) << "Stopping an unused meter should leave elapsed time at zero";
+}
+
+//==================================================================================================
+
+// Test the Print() method
+TEST_F(OSD_PerfMeterTest, PrintMethod)
+{
+  // Create and start the meter
+  const TCollection_AsciiString meterName = "PrintTestMeter";
+  OSD_PerfMeter                 meter(meterName);
+
+  // Do some work
+  DoSomeWork();
+
+  // Stop the meter
+  meter.Stop();
+
+  // Get the printed output
+  std::string output = meter.Print().ToCString();
+
+  // Verify output contains necessary information
+  EXPECT_TRUE(output.find(meterName.ToCString()) != std::string::npos)
+    << "Print output should contain meter name";
+
+  // Verify output contains elapsed time info (we can't check exact time,
+  // but there should be numbers)
+  EXPECT_TRUE(output.find_first_of("0123456789") != std::string::npos)
+    << "Print output should contain elapsed time values";
+
+  EXPECT_TRUE(output.find("sec") != std::string::npos)
+    << "Print output should contain millisecond units";
+}
+
+//==================================================================================================
+
+// Test the Kill() method
+TEST_F(OSD_PerfMeterTest, KillMethod)
+{
+  // Create and start the meter
+  OSD_PerfMeter meter("KillTestMeter");
+
+  // Do some work
+  DoSomeWork();
+
+  // Stop the meter
+  meter.Stop();
+
+  // Verify we have non-zero elapsed time
+  double elapsed = meter.Elapsed();
+  EXPECT_GT(elapsed, 0.0) << "Meter should have recorded time before Kill";
+
+  // Kill the meter
+  meter.Kill();
+
+  // Verify elapsed time is reset
+  double elapsedAfterKill = meter.Elapsed();
+  EXPECT_EQ(elapsedAfterKill, 0.0) << "Elapsed time should be reset after Kill";
+
+  // Verify killing a meter makes it disappear from the global list
+  std::string allMeters = OSD_PerfMeter::PrintALL().ToCString();
+  EXPECT_TRUE(allMeters.find("KillTestMeter") == std::string::npos)
+    << "Killed meter should not appear in PrintALL output";
+}
+
+//==================================================================================================
+
+// Test Kill method on a running meter
+TEST_F(OSD_PerfMeterTest, KillRunningMeter)
+{
+  // Create and start the meter
+  OSD_PerfMeter meter("KillRunningMeter");
+
+  // Don't stop the meter, kill it while running
+  meter.Kill();
+
+  // Verify elapsed time is reset
+  double elapsedAfterKill = meter.Elapsed();
+  EXPECT_EQ(elapsedAfterKill, 0.0) << "Elapsed time should be reset after Kill";
+
+  // Start the meter again to verify it's usable after being killed
+  meter.Init("KillRunningMeter");
+  meter.Start();
+  DoSomeWork();
+  meter.Stop();
+
+  // Verify it records time correctly after being killed and restarted
+  EXPECT_GT(meter.Elapsed(), 0.0) << "Meter should record time after Kill and restart";
+}
index 60d7d10b0a0e917a00452ab8b698b10f53c83b68..2cc04b9cbbdf184487e3e6c4432a3309cf36a6ca 100644 (file)
@@ -66,7 +66,6 @@ set(OCCT_OSD_FILES
   OSD_Path.cxx
   OSD_Path.hxx
   OSD_PerfMeter.cxx
-  OSD_PerfMeter.h
   OSD_PerfMeter.hxx
   OSD_Process.cxx
   OSD_Process.hxx
index fd04df3b48a79dc2e46c5dac84d90f9f87cd6b61..607fe517580f1ee7febecc5a7b82e761deb64ff4 100644 (file)
  commercial license or contractual agreement.
 */
 
-/*======================================================================
- */
-/*Purpose :       Set of functions to measure the CPU user time
- */
-/*25/09/2001 : AGV : (const char *) in prototypes;
- */
-/*09/11/2001 : AGV : Add functions perf_*_imeter for performance
- */
-/*Add function perf_tick_meter
- */
-/*14/05/2002 : AGV : Portability UNIX/Windows
- */
-/*======================================================================*/
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <OSD_Chronometer.hxx>
-#include <OSD_PerfMeter.h>
+#include <OSD_PerfMeter.hxx>
 
-/*======================================================================
-        DEFINITIONS
-======================================================================*/
+#include <OSD_Chronometer.hxx>
 
-typedef Standard_Real PERF_TIME;
+#include <unordered_map>
 
-#define PICK_TIME(_utime)                                                                          \
-  {                                                                                                \
-    Standard_Real ktime;                                                                           \
-    OSD_Chronometer::GetThreadCPU(_utime, ktime);                                                  \
-  }
-
-typedef struct
+// Simple stopwatch class to measure elapsed time
+// and provides methods to start, stop, and get the elapsed time in seconds.
+class Stopwatch
 {
-  char*     name;       /* identifier */
-  PERF_TIME cumul_time; /* cumulative time */
-  PERF_TIME start_time; /* to store start time */
-  int       nb_enter;   /* number of enters */
-} t_TimeCounter;
-
-#define MAX_METERS 100
-
-static t_TimeCounter MeterTable[MAX_METERS];
-static int           nb_meters = 0;
-
-static int find_meter(const char* const MeterName);
-static int _perf_init_meter(const char* const MeterName, const int doFind);
-
-/*======================================================================
-Function :      perf_init_meter
-Purpose  :      Creates new counter (if it is absent) identified by
-                MeterName and resets its cumulative value
-Returns  :      iMeter if OK, -1 if alloc problem
-======================================================================*/
-int perf_init_meter(const char* const MeterName)
+public:
+  // Constructor initializes the stopwatch.
+  // It does not start the stopwatch.
+  Stopwatch();
+
+  // Starts the stopwatch. If it is already running, it resets the start time.
+  void Start();
+
+  // Stops the stopwatch. If it is already stopped, it does nothing.
+  void Stop();
+
+  // Returns the elapsed time in seconds since the stopwatch was started.
+  // If the stopwatch is still running, it returns the time since the last start.
+  // If the stopwatch was stopped, it returns the time between the last start and stop.
+  // If the stopwatch was never started, it returns 0.
+  double Elapsed() const;
+
+  // Returns true if the stopwatch is currently running.
+  // Returns false if the stopwatch is stopped or was never started.
+  inline bool IsRunning() const;
+
+  // Returns true if the stopwatch has been started at least once and has a non-zero elapsed time.
+  // Returns false if the stopwatch was never started or has zero elapsed time.
+  inline bool IsActive() const;
+
+private:
+  // Returns the current time in seconds.
+  static double getTime();
+
+private:
+  double myStartTime; //< The time when the stopwatch was started.
+  double myEndTime;   //< The time when the stopwatch was stopped.
+                      //  Equal to myStartTime if the stopwatch is
+                      //  running or was never started.
+  bool myIsTicking;   //< Indicates whether the stopwatch is
+                      //  currently running.
+};
+
+//==================================================================================================
+
+Stopwatch::Stopwatch()
+    : myStartTime(getTime()),
+      myEndTime(myStartTime),
+      myIsTicking(false)
 {
-  return _perf_init_meter(MeterName, ~0);
 }
 
-/*======================================================================
-Function :      perf_tick_meter
-Purpose  :      Increments the counter of meter MeterName without changing
-                its state with respect to measurement of time.
-        creates new meter if there is no such meter
-Returns  :      iMeter if OK, -1 if no such meter and cannot create a new one
-======================================================================*/
-int perf_tick_meter(const char* const MeterName)
+//==================================================================================================
+
+void Stopwatch::Start()
 {
-  int ic = find_meter(MeterName);
+  myStartTime = getTime();
+  myIsTicking = true;
+}
+
+//==================================================================================================
 
-  if (ic == -1)
+void Stopwatch::Stop()
+{
+  if (!myIsTicking)
   {
-    /* create new meter */
-    ic = _perf_init_meter(MeterName, 0);
+    return;
   }
 
-  if (ic >= 0)
-    MeterTable[ic].nb_enter++;
+  myEndTime   = getTime();
+  myIsTicking = false;
+}
 
-  return ic;
+//==================================================================================================
+
+double Stopwatch::Elapsed() const
+{
+  const double anEndTime = myIsTicking ? getTime() : myEndTime;
+  return anEndTime - myStartTime;
 }
 
-/*======================================================================
-Function :      perf_tick_imeter
-Purpose  :      Increments the counter of meter iMeter without changing
-                its state with respect to measurement of time.
-Returns  :      iMeter if OK, -1 if no such meter
-======================================================================*/
-int perf_tick_imeter(const int iMeter)
+//==================================================================================================
+
+bool Stopwatch::IsRunning() const
 {
-  if (iMeter >= 0 && iMeter < nb_meters)
-  {
-    MeterTable[iMeter].nb_enter++;
-    return iMeter;
-  }
-  return -1;
+  return myIsTicking;
 }
 
-/*======================================================================
-Function :      perf_start_meter
-Purpose  :      Forces meter MeterName to begin to count by remembering
-                the current data of timer;
-        creates new meter if there is no such meter
-Returns  :      iMeter if OK, -1 if no such meter and cannot create a new one
-======================================================================*/
-int perf_start_meter(const char* const MeterName)
+//==================================================================================================
+
+bool Stopwatch::IsActive() const
 {
-  int ic = find_meter(MeterName);
+  return myIsTicking || (myEndTime - myStartTime) > 0.0;
+}
 
-  if (ic == -1)
-  {
-    /* create new meter */
-    ic = _perf_init_meter(MeterName, 0);
-  }
+//==================================================================================================
 
-  if (ic >= 0)
-    PICK_TIME(MeterTable[ic].start_time)
+double Stopwatch::getTime()
+{
+  Standard_Real aUserSeconds   = 0.0;
+  Standard_Real aSystemSeconds = 0.0;
+  OSD_Chronometer::GetThreadCPU(aUserSeconds, aSystemSeconds);
+  (void)(aSystemSeconds); // Unused variable
+  return aUserSeconds;
+}
 
-  return ic;
+//==================================================================================================
+
+// Singleton class to manage multiple stopwatches.
+// It provides methods to create, retrieve, and print stopwatches by name.
+// It also handles the lifetime of the stopwatches and prints their results when the program ends.
+// The class is designed to be used as a singleton, ensuring that there is only one instance of the
+// stopwatch manager throughout the program.
+class StopwatchStorage
+{
+private:
+  StopwatchStorage()                                   = default;
+  StopwatchStorage(const StopwatchStorage&)            = delete;
+  StopwatchStorage& operator=(const StopwatchStorage&) = delete;
+  StopwatchStorage(StopwatchStorage&&)                 = delete;
+  StopwatchStorage& operator=(StopwatchStorage&&)      = delete;
+
+  ~StopwatchStorage() { PrintAll(); }
+
+public:
+  // Returns the singleton instance of the StopwatchStorage class.
+  static StopwatchStorage& Instance();
+
+  // Retrieves a stopwatch by name. If the stopwatch does not exist, it returns nullptr.
+  // If the stopwatch exists, it returns a pointer to the stopwatch.
+  // This allows the user to access and manipulate the stopwatch directly.
+  // @param theName The name of the stopwatch to retrieve.
+  // @return A pointer to the stopwatch if it exists, nullptr otherwise.
+  Stopwatch* GetStopwatch(const std::string& theName);
+
+  // Creates a new stopwatch with the specified name.
+  // If a stopwatch with the same name already exists, it will be replaced.
+  // @param theName The name of the stopwatch to create.
+  // @return A reference to the created stopwatch.
+  Stopwatch& CreateStopwatch(const std::string& theName);
+
+  // Checks if a stopwatch with the specified name exists.
+  // This method allows the user to check if a stopwatch is already created before attempting to
+  // create or retrieve it.
+  // @param theName The name of the stopwatch to check.
+  // @return True if the stopwatch exists, false otherwise.
+  bool HasStopwatch(const std::string& theName) const;
+
+  // Deletes a stopwatch with the specified name.
+  // If the stopwatch does not exist, it does nothing.
+  // This method allows the user to remove a stopwatch from the storage.
+  // @param theName The name of the stopwatch to delete.
+  // @return True if the stopwatch was successfully deleted, false otherwise.
+  void KillStopwatch(const std::string& theName);
+
+  // Clears all stopwatches from the storage.
+  // This method removes all stopwatches and resets the storage to its initial state.
+  // It is useful for cleaning up the storage when it is no longer needed.
+  void Clear();
+
+  // Prints the results of a specific stopwatch by name.
+  // If the stopwatch does not exist, it does nothing.
+  // If the stopwatch is still running, it prints a warning message.
+  // If the stopwatch was never started, it prints a message indicating that.
+  // @param theName The name of the stopwatch to print.
+  // @return A string containing the results of the stopwatch.
+  std::string Print(const std::string& theName) const;
+
+  // Prints the results of all stopwatches in the storage.
+  // It iterates through all stopwatches and prints their results.
+  // If a stopwatch is still running, it prints a warning message.
+  // If a stopwatch was never started, it prints a message indicating that.
+  // @return A string containing the results of all stopwatches.
+  std::string PrintAll() const;
+
+private:
+  // Helper method to print the results of a specific stopwatch.
+  // It formats the output and appends it to the provided output string.
+  // @param theName The name of the stopwatch to print.
+  // @param theOutput The output string to append the results to.
+  void print(const std::string& theName, std::string& theOutput) const;
+
+private:
+  std::unordered_map<std::string, Stopwatch> myStopwatches; //< Map to store stopwatches by name.
+};
+
+//==================================================================================================
+
+StopwatchStorage& StopwatchStorage::Instance()
+{
+  static StopwatchStorage instance;
+  return instance;
 }
 
-/*======================================================================
-Function :      perf_start_imeter
-Purpose  :      Forces meter with number iMeter to begin count by remembering
-                the current data of timer;
-        the meter must be previously created
-Returns  :      iMeter if OK, -1 if no such meter
-======================================================================*/
-int perf_start_imeter(const int iMeter)
+//===================================================================================================
+
+Stopwatch* StopwatchStorage::GetStopwatch(const std::string& theName)
 {
-  if (iMeter >= 0 && iMeter < nb_meters)
-  {
-    PICK_TIME(MeterTable[iMeter].start_time)
-    return iMeter;
-  }
-  return -1;
+  auto it = myStopwatches.find(theName);
+  return (it != myStopwatches.end()) ? &it->second : nullptr;
 }
 
-/*======================================================================
-Function :      perf_stop_meter
-Purpose  :      Forces meter MeterName to stop and cumulate time elapsed
-                since start
-Returns  :      iMeter if OK, -1 if no such meter or it is has not been started
-======================================================================*/
-int perf_stop_meter(const char* const MeterName)
+//===================================================================================================
+
+Stopwatch& StopwatchStorage::CreateStopwatch(const std::string& theName)
 {
-  const int ic = find_meter(MeterName);
+  myStopwatches[theName] = Stopwatch();
+  return myStopwatches[theName];
+}
 
-  if (ic >= 0 && MeterTable[ic].start_time)
-  {
-    t_TimeCounter* const ptc = &MeterTable[ic];
-    PERF_TIME            utime;
-    PICK_TIME(utime)
-    ptc->cumul_time += utime - ptc->start_time;
-    ptc->start_time = 0;
-    ptc->nb_enter++;
-  }
+//===================================================================================================
 
-  return ic;
+bool StopwatchStorage::HasStopwatch(const std::string& theName) const
+{
+  return myStopwatches.find(theName) != myStopwatches.end();
 }
 
-/*======================================================================
-Function :      perf_stop_imeter
-Purpose  :      Forces meter with number iMeter to stop and cumulate the time
-                elapsed since the start
-Returns  :      iMeter if OK, -1 if no such meter or it is has not been started
-======================================================================*/
-int perf_stop_imeter(const int iMeter)
+//===================================================================================================
+
+void StopwatchStorage::KillStopwatch(const std::string& theName)
 {
-  if (iMeter >= 0 && iMeter < nb_meters)
-  {
-    t_TimeCounter* const ptc = &MeterTable[iMeter];
-    if (ptc->start_time)
-    {
-      PERF_TIME utime;
-      PICK_TIME(utime)
-      ptc->cumul_time += utime - ptc->start_time;
-      ptc->start_time = 0;
-      ptc->nb_enter++;
-      return iMeter;
-    }
-  }
-  return -1;
+  myStopwatches.erase(theName);
 }
 
-/*======================================================================
-Function :      perf_get_meter
-Purpose  :      Tells the time cumulated by meter MeterName and the number
-                of enters to this meter
-Output   :      *nb_enter, *seconds if the pointers != NULL
-Returns  :      iMeter if OK, -1 if no such meter
-======================================================================*/
-int perf_get_meter(const char* const MeterName, int* nb_enter, double* seconds)
+//===================================================================================================
+
+void StopwatchStorage::Clear()
 {
-  const int ic = find_meter(MeterName);
+  myStopwatches.clear();
+}
+
+//===================================================================================================
 
-  if (ic >= 0)
+std::string StopwatchStorage::Print(const std::string& theName) const
+{
+  std::string anOutput;
+  auto        it = myStopwatches.find(theName);
+  if (it != myStopwatches.end())
   {
-    if (nb_enter)
-      *nb_enter = MeterTable[ic].nb_enter;
-    if (seconds)
-      *seconds = MeterTable[ic].cumul_time;
+    print(theName, anOutput);
   }
-  return ic;
+  return anOutput;
 }
 
-/*======================================================================
-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 if reset is non-null
-======================================================================*/
-void perf_print_all_meters(int reset)
+//===================================================================================================
+
+std::string StopwatchStorage::PrintAll() const
 {
-  char buffer[MAX_METERS * 256];
-  perf_sprint_all_meters(buffer, MAX_METERS * 256, reset);
-  printf("%s", buffer);
+  std::string anOutput;
+  for (const auto& aStopwatch : myStopwatches)
+  {
+    print(aStopwatch.first, anOutput);
+  }
+  return anOutput;
 }
 
-/*======================================================================
-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)
+//===================================================================================================
+
+void StopwatchStorage::print(const std::string& theName, std::string& theOutput) const
 {
-  char string[256];
+  auto it = myStopwatches.find(theName);
+  if (it == myStopwatches.end())
+  {
+    return;
+  }
 
-  int i;
-  for (i = 0; i < nb_meters; i++)
+  if (!it->second.IsActive())
   {
-    const t_TimeCounter* const ptc = &MeterTable[i];
-    if (ptc && ptc->nb_enter)
-    {
-      int n =
-        sprintf(string,
-                "          Perf meter results               :   enters  seconds  microsec/enter\n");
-      if (n < length)
-      {
-        memcpy(buffer, string, n);
-        buffer += n;
-        length -= n;
-      }
-      break;
-    }
+    theOutput += "Stopwatch " + theName + " have never been started.\n";
+    return;
   }
 
-  while (i < nb_meters)
+  if (it->second.IsRunning())
   {
-    t_TimeCounter* const ptc = &MeterTable[i++];
-
-    if (ptc && ptc->nb_enter)
-    {
-      const double secs = ptc->cumul_time;
-
-      int n = 0;
-      if (ptc->start_time)
-        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;
-      }
-    }
+    theOutput += "Warning: Stopwatch " + theName + " is still running.\n";
+    return;
   }
-  *buffer = '\0';
+  theOutput += "Stopwatch " + theName + ": " + std::to_string(it->second.Elapsed()) + " sec\n";
 }
 
-/*======================================================================
-Function :      perf_close_meter
-Purpose  :      Prints out a meter and resets it
-Returns  :      none
-======================================================================*/
-void perf_close_meter(const char* const MeterName)
+//==================================================================================================
+
+OSD_PerfMeter::OSD_PerfMeter(const TCollection_AsciiString& theMeterName, const bool theToAutoStart)
 {
-  perf_close_imeter(find_meter(MeterName));
+  Init(theMeterName);
+
+  if (theToAutoStart)
+  {
+    Start();
+  }
 }
 
-/*======================================================================
-Function :      perf_close_imeter
-Purpose  :      Prints out a meter and resets it
-Returns  :      none
-======================================================================*/
-void perf_close_imeter(const int iMeter)
+//==================================================================================================
+
+OSD_PerfMeter::~OSD_PerfMeter() {}
+
+//==================================================================================================
+
+void OSD_PerfMeter::Init(const TCollection_AsciiString& theMeterName)
 {
-  if (iMeter >= 0 && iMeter < nb_meters && MeterTable[iMeter].nb_enter)
+  myMeterName = theMeterName;
+  if (!StopwatchStorage::Instance().HasStopwatch(myMeterName.ToCString()))
   {
-    t_TimeCounter* const ptc = &MeterTable[iMeter];
-    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;
+    StopwatchStorage::Instance().CreateStopwatch(myMeterName.ToCString());
   }
 }
 
-/*======================================================================
-Function :      perf_destroy_all_meters
-Purpose  :      Deletes all meters and frees memory
-Returns  :      none
-======================================================================*/
-void perf_destroy_all_meters(void)
+//==================================================================================================
+
+void OSD_PerfMeter::Start() const
 {
-  int i;
-  for (i = 0; i < nb_meters; i++)
-    free(MeterTable[i].name);
-  nb_meters = 0;
+  Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
+  if (aStopwatch != nullptr)
+  {
+    aStopwatch->Start();
+  }
 }
 
-/* agv - non portable: #pragma fini (perf_print_and_destroy)
-         using atexit instead (see _perf_init_meter below)            */
+//==================================================================================================
 
-void perf_print_and_destroy(void)
+void OSD_PerfMeter::Stop() const
 {
-  perf_print_all_meters(0);
-  perf_destroy_all_meters();
+  Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
+  if (aStopwatch != nullptr)
+  {
+    aStopwatch->Stop();
+  }
 }
 
-/*======================================================================
-Function :      _perf_init_meter
-Purpose  :      Creates new counter (if it is absent) identified by
-                MeterName and resets its cumulative value
-Returns  :      index of meter if OK, -1 if alloc problem
-Remarks  :      For internal use in this module
-======================================================================*/
-static int _perf_init_meter(const char* const MeterName, const int doFind)
+//==================================================================================================
+
+double OSD_PerfMeter::Elapsed() const
 {
-  static int hasbeencalled = 0;
-  int        ic            = -1;
-  if (doFind)
-    ic = find_meter(MeterName);
+  Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
+  return aStopwatch ? aStopwatch->Elapsed() : 0.0;
+}
 
-  if (ic == -1)
-  {
-    if (nb_meters >= MAX_METERS)
-      return 0;
-    ic = nb_meters;
+//==================================================================================================
 
-    MeterTable[ic].name = strdup(MeterName);
-    if (!MeterTable[ic].name)
-      return -1;
+void OSD_PerfMeter::Kill() const
+{
+  StopwatchStorage::Instance().KillStopwatch(myMeterName.ToCString());
+}
 
-    nb_meters++;
-  }
+//==================================================================================================
 
-  MeterTable[ic].cumul_time = 0;
-  MeterTable[ic].start_time = 0;
-  MeterTable[ic].nb_enter   = 0;
-  if (hasbeencalled == 0)
+TCollection_AsciiString OSD_PerfMeter::Print() const
+{
+  Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
+  if (aStopwatch != nullptr)
   {
-    atexit(perf_print_and_destroy);
-    hasbeencalled = ~0;
+    const std::string anOutput = StopwatchStorage::Instance().Print(myMeterName.ToCString());
+    return anOutput.c_str();
   }
-  return ic;
+  return "";
+}
+
+//==================================================================================================
+
+TCollection_AsciiString OSD_PerfMeter::PrintALL()
+{
+  const std::string anOutput = StopwatchStorage::Instance().PrintAll();
+  return anOutput.c_str();
 }
 
-/*======================================================================
-Function :      find_meter
-Purpose  :      Finds the meter MeterName in the MeterTable
-Returns  :      Index of meter object, -1 if not found
-Remarks  :      For internal use in this module
-======================================================================*/
-static int find_meter(const char* const MeterName)
+//==================================================================================================
+
+void OSD_PerfMeter::ResetALL()
 {
-  int i;
-  for (i = 0; i < nb_meters; i++)
-    if (!strcmp(MeterTable[i].name, MeterName))
-      return i;
-  return -1;
+  StopwatchStorage::Instance().Clear();
 }
diff --git a/src/FoundationClasses/TKernel/OSD/OSD_PerfMeter.h b/src/FoundationClasses/TKernel/OSD/OSD_PerfMeter.h
deleted file mode 100644 (file)
index 263c29c..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- Copyright (c) 1999-2014 OPEN CASCADE SAS
-
- This file is part of Open CASCADE Technology software library.
-
- This library is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License version 2.1 as published
- by the Free Software Foundation, with special exception defined in the file
- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
- distribution for complete text of the license and disclaimer of any warranty.
-
- Alternatively, this file may be used under the terms of Open CASCADE
- commercial license or contractual agreement.
-*/
-
-#ifndef _OSD_PERFMETER_H
-#define _OSD_PERFMETER_H
-
-/**
- * Macros for convenient and fast usage of meters.
- * Define PERF_ENABLE_METERS to make them available.
- */
-#ifdef PERF_ENABLE_METERS
-
-  /**
-   * @def PERF_START_METER(theMeterName)
-   * Forces meter MeterName to begin to count by remembering the current data of timer.
-   * Creates new meter if there is no such meter.
-   */
-  #define PERF_START_METER(_m_name)                                                                \
-    {                                                                                              \
-      static int __iMeter = -1;                                                                    \
-      if (__iMeter >= 0)                                                                           \
-        perf_start_imeter(__iMeter);                                                               \
-      else                                                                                         \
-        __iMeter = perf_start_meter(_m_name);                                                      \
-    }
-
-  /**
-   * @def PERF_STOP_METER(theMeterName)
-   * Forces meter MeterName to stop and cumulate the time elapsed since the start.
-   */
-  #define PERF_STOP_METER(_m_name)                                                                 \
-    {                                                                                              \
-      static int __iMeter = -1;                                                                    \
-      if (__iMeter >= 0)                                                                           \
-        perf_stop_imeter(__iMeter);                                                                \
-      else                                                                                         \
-        __iMeter = perf_stop_meter(_m_name);                                                       \
-    }
-
-  /**
-   * @def PERF_TICK_METER(theMeterName)
-   * Increments the counter of meter MeterName without changing its state with respect to
-   * measurement of time. Creates new meter if there is no such meter. It is useful to count the
-   * number of enters to a part of code without wasting a time to measure CPU time.
-   */
-  #define PERF_TICK_METER(_m_name)                                                                 \
-    {                                                                                              \
-      static int __iMeter = -1;                                                                    \
-      if (__iMeter >= 0)                                                                           \
-        perf_tick_imeter(__iMeter);                                                                \
-      else                                                                                         \
-        __iMeter = perf_tick_meter(_m_name);                                                       \
-    }
-
-  /**
-   * @def PERF_CLOSE_METER(theMeterName)
-   * Prints out and resets the given meter.
-   */
-  #define PERF_CLOSE_METER(_m_name) perf_close_meter(_m_name);
-
-  /**
-   * @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(1);                                                                    \
-    }
-
-#else
-  #define PERF_TICK_METER(_m_name)
-  #define PERF_START_METER(_m_name)
-  #define PERF_STOP_METER(_m_name)
-  #define PERF_CLOSE_METER(_m_name)
-  #define PERF_PRINT_ALL()
-#endif
-
-/**
- * Creates new counter (if it is absent) identified by theMeterName and resets its cumulative value
- * @return meter global identifier if OK, -1 if alloc problem
- */
-Standard_EXPORTEXTERNC int perf_init_meter(const char* const theMeterName);
-
-/**
- * Forces meter theMeterName to begin to count by remembering the current data of timer.
- * Creates new meter if there is no such meter.
- * @return meter global identifier if OK, -1 if no such meter and cannot create a new one
- */
-Standard_EXPORTEXTERNC int perf_start_meter(const char* const theMeterName);
-
-/**
- * Forces meter with number theMeterId to begin count by remembering the current data of timer.
- * @return meter global identifier if OK, -1 if no such meter
- */
-Standard_EXPORTEXTERNC int perf_start_imeter(const int theMeterId);
-
-/**
- * Forces meter theMeterName to stop and cumulate the time elapsed since the start.
- * @return meter global identifier if OK, -1 if no such meter or it is has not been started
- */
-Standard_EXPORTEXTERNC int perf_stop_meter(const char* const theMeterName);
-
-/**
- * Forces meter with number theMeterId to stop and cumulate the time elapsed since the start.
- * @return meter global identifier if OK, -1 if no such meter or it is has not been started
- */
-Standard_EXPORTEXTERNC int perf_stop_imeter(const int theMeterId);
-
-/**
- * Increments the counter of meter theMeterName without changing its state with respect to
- * measurement of time. Creates new meter if there is no such meter.
- * @return meter global identifier if OK, -1 if no such meter and cannot create a new one
- */
-Standard_EXPORTEXTERNC int perf_tick_meter(const char* const theMeterName);
-
-/**
- * Increments the counter of meter theMeterId without changing its state with respect to measurement
- * of time.
- * @return meter global identifier if OK, -1 if no such meter
- */
-Standard_EXPORTEXTERNC int perf_tick_imeter(const int theMeterId);
-
-/**
- * Tells the time cumulated by meter theMeterName and the number of enters to this meter.
- * @param theNbEnter [OUT] number of enters if the pointer != NULL
- * @param theSeconds [OUT] seconds if the pointer != NULL
- * @return meter global identifier if OK, -1 if no such meter
- */
-Standard_EXPORTEXTERNC int perf_get_meter(const char* const theMeterName,
-                                          int*              theNbEnter,
-                                          double*           theSeconds);
-
-/**
- * Prints on stdout the cumulated time and the number of enters for the specified meter.
- */
-Standard_EXPORTEXTERNC void perf_close_meter(const char* const theMeterName);
-
-/**
- * Prints on stdout the cumulated time and the number of enters for the specified meter.
- */
-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_sprint_all_meters(char* buffer, int length, int reset);
-
-/**
- * Deletes all meters and frees memory.
- */
-Standard_EXPORTEXTERNC void perf_destroy_all_meters(void);
-
-/**
- * ATTENTION!!!
- * 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);
-
-#endif
index 47585586b0a2537a4eaacdbe338151f52f2ae9c1..b38155dd2f845be2308e1b06a43cd1dd34672e4b 100644 (file)
@@ -16,7 +16,8 @@
 #ifndef OSD_PerfMeter_HeaderFile
 #define OSD_PerfMeter_HeaderFile
 
-#include <OSD_PerfMeter.h>
+#include <Standard_Macro.hxx>
+#include <TCollection_AsciiString.hxx>
 
 //! This class enables measuring the CPU time between two points of code execution, regardless of
 //! the scope of these points of code. A meter is identified by its name (string). So multiple
 //! on stdout upon finish of the program. For details see OSD_PerfMeter.h
 class OSD_PerfMeter
 {
-
 public:
-  //! Constructs a void meter (to further call Init and Start)
-  OSD_PerfMeter()
-      : myIMeter(-1)
-  {
-  }
+  //! Constructs a void meter (to further call Init and Start).
+  Standard_EXPORT OSD_PerfMeter() = default;
 
-  //! Constructs and starts (if autoStart is true) the named meter
-  OSD_PerfMeter(const char* theMeter, const bool theToAutoStart = true)
-      : myIMeter(perf_get_meter(theMeter, 0, 0))
-  {
-    if (myIMeter < 0)
-      myIMeter = perf_init_meter(theMeter);
-    if (theToAutoStart)
-      Start();
-  }
+  //! Constructs and starts (if autoStart is true) the named meter.
+  //! @param theMeterName Name of the meter. If the meter with such name was already created,
+  //!        and hasn't been killed, it will be used.
+  //! @param theToAutoStart If true, the meter will be started immediately after creation.
+  //!        Otherwise, the user should call Start() method to start the meter.
+  //!        Note that if meter already exists, theToAutoStart == true will reset it.
+  Standard_EXPORT OSD_PerfMeter(const TCollection_AsciiString& theMeterName,
+                                const bool                     theToAutoStart = true);
 
-  //! Prepares the named meter
-  void Init(const char* theMeter)
-  {
-    myIMeter = perf_get_meter(theMeter, 0, 0);
-    if (myIMeter < 0)
-      myIMeter = perf_init_meter(theMeter);
-  }
+  //! Destructs this meter handler. Note that the meter itself is not destructed
+  //! and will be printed on stdout upon finish of the program. The meter with the name
+  //! Specified in the constructor can still be used in other places of the code.
+  Standard_EXPORT ~OSD_PerfMeter();
 
-  //! Starts the meter
-  void Start() const { perf_start_imeter(myIMeter); }
+  //! Prepares the named meter. If the meter with such name was already created,
+  //! it will be used. Otherwise, a new meter will be created.
+  Standard_EXPORT void Init(const TCollection_AsciiString& theMeterName);
 
-  //! Stops the meter
-  void Stop() const { perf_stop_imeter(myIMeter); }
+  //! Starts the meter. If the meter was already started, it will be reset.
+  //! Note that the meter with the name specified in the constructor can still be used
+  //! in other places of the code.
+  Standard_EXPORT void Start() const;
 
-  //! Increments the counter w/o time measurement
-  void Tick() const { perf_tick_imeter(myIMeter); }
+  //! Stops the meter.
+  Standard_EXPORT void Stop() const;
 
-  //! Outputs the meter data and resets it to initial state
-  void Flush() const { perf_close_imeter(myIMeter); }
+  //! Returns the elapsed time in seconds since the meter was started.
+  Standard_EXPORT double Elapsed() const;
 
-  //! Assures stopping upon destruction
-  ~OSD_PerfMeter()
-  {
-    if (myIMeter >= 0)
-      Stop();
-  }
+  //! Outputs the meter data and resets it to initial state.
+  Standard_EXPORT void Kill() const;
 
-private:
-  OSD_PerfMeter(const OSD_PerfMeter&);
-  OSD_PerfMeter& operator=(const OSD_PerfMeter&);
+  //! Prints the data of this meter.
+  Standard_EXPORT TCollection_AsciiString Print() const;
+
+  //! Prints the data of all meters with non-zero elapsed time.
+  Standard_EXPORT static TCollection_AsciiString PrintALL();
 
-protected:
-  int myIMeter;
+  //! Resets all meters.
+  Standard_EXPORT static void ResetALL();
+
+private:
+  TCollection_AsciiString myMeterName;
 };
 
 #endif // OSD_PerfMeter_HeaderFile
diff --git a/tests/bugs/fclasses/bug23237 b/tests/bugs/fclasses/bug23237
deleted file mode 100755 (executable)
index dd9aaa3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-puts "============"
-puts "CR23237"
-puts "==========="
-puts ""
-################################################
-# Bug in OSD_PerfMeter
-################################################
-
-pload QAcommands
-
-OCC23237
\ No newline at end of file