From 78fc102df1e574b504b922896944e8bebd8ca1c2 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Mon, 4 Mar 2024 11:45:29 +0100
Subject: [PATCH] ENH: minor reduction in allocations for inactive profiling
 (#3112)

- avoid string conversion/concatenation unless profiling hooks
  are possible (ie, active or Extrae is loaded).
---
 .../functionObjectList/functionObjectList.C   | 16 ++--
 src/OpenFOAM/global/argList/argList.C         |  1 +
 .../global/profiling/profilingTrigger.C       | 42 +++++----
 .../global/profiling/profilingTrigger.H       | 88 ++++++++++++++-----
 .../solvers/smoothSolver/smoothSolver.C       |  4 +-
 .../faOption/faOptionListTemplates.C          | 10 +--
 .../general/fvOptions/fvOptionListTemplates.C | 17 ++--
 .../fvMatrices/fvMatrix/fvMatrixSolve.C       |  2 +-
 .../fvScalarMatrix/fvScalarMatrix.C           |  2 +-
 .../adjointSpalartAllmaras.C                  | 11 ++-
 10 files changed, 130 insertions(+), 63 deletions(-)

diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C
index ae8aed9e057..c9b108be34f 100644
--- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C
+++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C
@@ -651,7 +651,7 @@ bool Foam::functionObjectList::execute(bool writeProperties)
                     addProfiling
                     (
                         fo,
-                        "functionObject::" + objName + "::execute"
+                        "functionObject::", objName, "::execute"
                     );
 
                     ok = funcObj.execute() && ok;
@@ -697,7 +697,7 @@ bool Foam::functionObjectList::execute(bool writeProperties)
                     addProfiling
                     (
                         fo,
-                        "functionObject::" + objName + ":write"
+                        "functionObject::", objName, ":write"
                     );
 
                     ok = funcObj.write() && ok;
@@ -753,7 +753,7 @@ bool Foam::functionObjectList::execute(bool writeProperties)
                     addProfiling
                     (
                         fo,
-                        "functionObject::" + objName + "::execute"
+                        "functionObject::", objName, "::execute"
                     );
 
                     ok = funcObj.execute() && ok;
@@ -764,7 +764,7 @@ bool Foam::functionObjectList::execute(bool writeProperties)
                     addProfiling
                     (
                         fo,
-                        "functionObject::" + objName + ":write"
+                        "functionObject::", objName, ":write"
                     );
 
                     ok = funcObj.write() && ok;
@@ -863,7 +863,7 @@ bool Foam::functionObjectList::end()
 
             try
             {
-                addProfiling(fo, "functionObject::" + objName + "::end");
+                addProfiling(fo, "functionObject::", objName, "::end");
                 ok = funcObj.end() && ok;
             }
             catch (const Foam::error& err)
@@ -925,7 +925,7 @@ bool Foam::functionObjectList::adjustTimeStep()
             addProfiling
             (
                 fo,
-                "functionObject::" + objName + "::adjustTimeStep"
+                "functionObject::", objName, "::adjustTimeStep"
             );
 
             ok = funcObj.adjustTimeStep() && ok;
@@ -1090,7 +1090,7 @@ bool Foam::functionObjectList::read()
                         addProfiling
                         (
                             fo,
-                            "functionObject::" + objPtr->name() + "::read"
+                            "functionObject::", objPtr->name(), "::read"
                         );
 
                         enabled = objPtr->read(dict);
@@ -1117,7 +1117,7 @@ bool Foam::functionObjectList::read()
                     addProfiling
                     (
                         fo,
-                        "functionObject::" + key + "::new"
+                        "functionObject::", key, "::new"
                     );
                     if (needsTimeControl)
                     {
diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index a94437514a6..021abff1575 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -1016,6 +1016,7 @@ Foam::argList::argList
         runControl_.runPar(argc, argv);
     }
 
+    // addProfiling(argList, "argList");
 
     // ------------------------------------------------------------------------
 
diff --git a/src/OpenFOAM/global/profiling/profilingTrigger.C b/src/OpenFOAM/global/profiling/profilingTrigger.C
index 95d6fadc63f..aa4a545d5d5 100644
--- a/src/OpenFOAM/global/profiling/profilingTrigger.C
+++ b/src/OpenFOAM/global/profiling/profilingTrigger.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2009-2016 Bernhard Gschaider
-    Copyright (C) 2016-2023 OpenCFD Ltd.
+    Copyright (C) 2016-2024 OpenCFD Ltd.
     Copyright (C) 2023 Josep Pocurull Serra, Barcelona Supercomputing Center
 -------------------------------------------------------------------------------
 License
@@ -140,26 +140,33 @@ static void close_extrae_region()
 #endif  /* HAVE_EXTRAE */
 
 
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::profilingTrigger::profilingTrigger() noexcept
-:
-    ptr_(nullptr)
-{}
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
+bool Foam::profilingTrigger::possible() noexcept
+{
+    return
+    (
+        profiling::active()
+        #ifdef HAVE_EXTRAE
+     || bool(Extrae_event)
+        #endif
+    );
+}
 
-Foam::profilingTrigger::profilingTrigger(const char* name)
-:
-    profilingTrigger(std::string(name))
-{}
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-Foam::profilingTrigger::profilingTrigger(const std::string& name)
-:
-    ptr_(profiling::New(name))
+void Foam::profilingTrigger::enter(const std::string& name)
 {
+    // debug:  std::cerr<< "enter profiling: " << name << '\n';
+
+    ptr_ = profiling::New(name);
+
     #ifdef HAVE_EXTRAE
-    if (Extrae_event) open_extrae_region(std::string(name));
+    if (Extrae_event)
+    {
+        open_extrae_region(name);
+    }
     #endif
 }
 
@@ -183,7 +190,10 @@ bool Foam::profilingTrigger::running() const noexcept
 void Foam::profilingTrigger::stop()
 {
     #ifdef HAVE_EXTRAE
-    if (Extrae_event) close_extrae_region();
+    if (Extrae_event)
+    {
+        close_extrae_region();
+    }
     #endif
 
     if (ptr_)
diff --git a/src/OpenFOAM/global/profiling/profilingTrigger.H b/src/OpenFOAM/global/profiling/profilingTrigger.H
index e1242a06cb6..2a29438632e 100644
--- a/src/OpenFOAM/global/profiling/profilingTrigger.H
+++ b/src/OpenFOAM/global/profiling/profilingTrigger.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2009-2016 Bernhard Gschaider
-    Copyright (C) 2016-2023 OpenCFD Ltd.
+    Copyright (C) 2016-2024 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,7 +38,7 @@ SourceFiles
 #ifndef Foam_profilingTrigger_H
 #define Foam_profilingTrigger_H
 
-#include "word.H"
+#include <string>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -57,7 +57,42 @@ class profilingTrigger
     // Private Data Members
 
         //- The profiling information
-        profilingInformation *ptr_;
+        profilingInformation* ptr_;
+
+
+    // Private Member Functions
+
+        //- True if any profiling hooks are possible
+        static bool possible() noexcept;
+
+        //- Helper: string concatenation (no-op)
+        static inline void string_concat(std::string& output) {}
+
+        //- Helper: string concatenation (loop)
+        template<class StringType, class... StringArgs>
+        static inline void string_concat
+        (
+            std::string& output,
+            const StringType& str,
+            StringArgs&&... args
+        )
+        {
+            output += str;
+            string_concat(output, std::forward<StringArgs>(args)...);
+        }
+
+        //- Enter profiling section
+        void enter(const std::string& name);
+
+        //- Trigger entering of profiling section
+        template<class... StringArgs>
+        void trigger(std::string name, StringArgs&&... args)
+        {
+            string_concat(name, std::forward<StringArgs>(args)...);
+            // No checking for empty name (should not occur)
+            enter(name);
+        }
+
 
 public:
 
@@ -73,29 +108,37 @@ public:
     // Constructors
 
         //- Default construct, no profiling trigger
-        profilingTrigger() noexcept;
-
-        //- Construct profiling with given description.
-        //  Descriptions beginning with 'application::' are reserved for
-        //  internal use.
-        explicit profilingTrigger(const char* name);
+        constexpr profilingTrigger() noexcept : ptr_(nullptr) {}
 
-        //- Construct profiling with given description.
+        //- Start profiling section (if profiling is active)
+        //- with given description.
+        //  The description is generated by string concatenation of the
+        //  parameters.
         //  Descriptions beginning with 'application::' are reserved for
         //  internal use.
-        explicit profilingTrigger(const std::string& name);
-
-
-    //- Destructor
+        template<class... StringArgs>
+        explicit profilingTrigger(StringArgs&&... description)
+        :
+            ptr_(nullptr)
+        {
+            if (possible())
+            {
+                // Delay string concatenation until actually needed
+                trigger(std::forward<StringArgs>(description)...);
+            }
+        }
+
+
+    //- Destructor, calls stop()
     ~profilingTrigger();
 
 
     // Member Functions
 
-        //- True if the triggered profiling is active
+        //- True if the triggered profiling section is active
         bool running() const noexcept;
 
-        //- Stop triggered profiling
+        //- Stop triggered profiling section
         void stop();
 };
 
@@ -108,10 +151,11 @@ public:
 
 // Macros
 
-//- Define profiling trigger with specified name and description string
+//- Define profiling trigger with specified name and description string.
+//- The description is generated by string concatenation.
 //  \sa endProfiling
-#define addProfiling(Name,Descr) \
-    ::Foam::profilingTrigger  profilingTriggerFor##Name(Descr)
+#define addProfiling(Name, ...) \
+    ::Foam::profilingTrigger  profilingTriggerFor##Name(__VA_ARGS__)
 
 //- Remove profiling with specified name
 //  \sa addProfiling
@@ -121,9 +165,11 @@ public:
 //- corresponding to the compiler-defined function name string
 //  \sa addProfiling
 #ifdef __GNUC__
-#define addProfilingInFunction(Name)  addProfiling(Name, __PRETTY_FUNCTION__)
+#define addProfilingInFunction(Name) \
+    ::Foam::profilingTrigger  profilingTriggerFor##Name(__PRETTY_FUNCTION__)
 #else
-#define addProfilingInFunction(Name)  addProfiling(Name, __func__)
+#define addProfilingInFunction(Name) \
+    ::Foam::profilingTrigger  profilingTriggerFor##Name(__func__)
 #endif
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
index 1c25d08ccba..127d20d7ac2 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
@@ -95,7 +95,7 @@ Foam::solverPerformance Foam::smoothSolver::solve
     // If the nSweeps_ is negative do a fixed number of sweeps
     if (nSweeps_ < 0)
     {
-        addProfiling(solve, "lduMatrix::smoother." + fieldName_);
+        addProfiling(solve, "lduMatrix::smoother.", fieldName_);
 
         autoPtr<lduMatrix::smoother> smootherPtr = lduMatrix::smoother::New
         (
@@ -163,7 +163,7 @@ Foam::solverPerformance Foam::smoothSolver::solve
          || !solverPerf.checkConvergence(tolerance_, relTol_, log_)
         )
         {
-            addProfiling(solve, "lduMatrix::smoother." + fieldName_);
+            addProfiling(solve, "lduMatrix::smoother.", fieldName_);
 
             autoPtr<lduMatrix::smoother> smootherPtr = lduMatrix::smoother::New
             (
diff --git a/src/faOptions/faOption/faOptionListTemplates.C b/src/faOptions/faOption/faOptionListTemplates.C
index 7445acae929..ab68dfd5552 100644
--- a/src/faOptions/faOption/faOptionListTemplates.C
+++ b/src/faOptions/faOption/faOptionListTemplates.C
@@ -50,7 +50,7 @@ Foam::tmp<Foam::faMatrix<Type>> Foam::fa::optionList::source
 
         if (fieldi != -1)
         {
-            addProfiling(faopt, "faOption()." + source.name());
+            addProfiling(faopt, "faOption().", source.name());
 
             source.setApplied(fieldi);
 
@@ -141,7 +141,7 @@ Foam::tmp<Foam::faMatrix<Type>> Foam::fa::optionList::operator()
 
         if (fieldi != -1)
         {
-            addProfiling(faopt, "faOption()." + source.name());
+            addProfiling(faopt, "faOption().", source.name());
 
             source.setApplied(fieldi);
 
@@ -193,7 +193,7 @@ Foam::tmp<Foam::faMatrix<Type>> Foam::fa::optionList::operator()
 
         if (fieldi != -1)
         {
-            addProfiling(faopt, "faOption()." + source.name());
+            addProfiling(faopt, "faOption().", source.name());
 
             source.setApplied(fieldi);
 
@@ -256,7 +256,7 @@ void Foam::fa::optionList::constrain(faMatrix<Type>& eqn)
 
         if (fieldi != -1)
         {
-            addProfiling(faopt, "faOption::constrain." + eqn.psi().name());
+            addProfiling(faopt, "faOption::constrain.", eqn.psi().name());
 
             source.setApplied(fieldi);
 
@@ -299,7 +299,7 @@ void Foam::fa::optionList::correct
 
         if (fieldi != -1)
         {
-            addProfiling(faopt, "faOption::correct." + source.name());
+            addProfiling(faopt, "faOption::correct.", source.name());
 
             source.setApplied(fieldi);
 
diff --git a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionListTemplates.C b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionListTemplates.C
index 201ecb634dc..b6e8d9aa07d 100644
--- a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionListTemplates.C
+++ b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionListTemplates.C
@@ -51,7 +51,7 @@ Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionList::source
 
         if (fieldi != -1)
         {
-            addProfiling(fvopt, "fvOption()." + source.name());
+            addProfiling(fvopt, "fvOption().", source.name());
 
             source.setApplied(fieldi);
 
@@ -138,7 +138,7 @@ Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionList::operator()
 
         if (fieldi != -1)
         {
-            addProfiling(fvopt, "fvOption()." + source.name());
+            addProfiling(fvopt, "fvOption().", source.name());
 
             source.setApplied(fieldi);
 
@@ -207,7 +207,7 @@ Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionList::operator()
 
         if (fieldi != -1)
         {
-            addProfiling(fvopt, "fvOption()." + source.name());
+            addProfiling(fvopt, "fvOption().", source.name());
 
             source.setApplied(fieldi);
 
@@ -321,7 +321,7 @@ void Foam::fv::optionList::constrain(fvMatrix<Type>& eqn)
 
         if (fieldi != -1)
         {
-            addProfiling(fvopt, "fvOption::constrain." + eqn.psi().name());
+            addProfiling(fvopt, "fvOption::constrain.", eqn.psi().name());
 
             source.setApplied(fieldi);
 
@@ -364,7 +364,7 @@ void Foam::fv::optionList::correct
 
         if (fieldi != -1)
         {
-            addProfiling(fvopt, "fvOption::correct." + source.name());
+            addProfiling(fvopt, "fvOption::correct.", source.name());
 
             source.setApplied(fieldi);
 
@@ -407,7 +407,7 @@ void Foam::fv::optionList::postProcessSens
 
         if (fieldi != -1)
         {
-            addProfiling(fvopt, "fvOption::postProcessSens." + source.name());
+            addProfiling(fvopt, "fvOption::postProcessSens.", source.name());
 
             const bool ok = source.isActive();
 
@@ -447,7 +447,10 @@ void Foam::fv::optionList::postProcessAuxSens
         if (fieldi != -1)
         {
             addProfiling
-                (fvopt, "fvOption::postProcessAuxSens." + source.name());
+            (
+                fvopt,
+                "fvOption::postProcessAuxSens.", source.name()
+            );
 
             const bool ok = source.isActive();
 
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
index 000306e3523..0a232e35b1a 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
@@ -68,7 +68,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregatedOrCoupled
     {
         regionName = psi_.mesh().name() + "::";
     }
-    addProfiling(solve, "fvMatrix::solve." + regionName + psi_.name());
+    addProfiling(solve, "fvMatrix::solve.", regionName, psi_.name());
 
     if (debug)
     {
diff --git a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
index a8d87158f8f..c23bd6a6dd7 100644
--- a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
+++ b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
@@ -72,7 +72,7 @@ Foam::fvMatrix<Foam::scalar>::solver
     {
         regionName = psi_.mesh().name() + "::";
     }
-    addProfiling(solve, "fvMatrix::solve." + regionName + psi_.name());
+    addProfiling(solve, "fvMatrix::solve.", regionName, psi_.name());
 
     if (debug)
     {
diff --git a/src/optimisation/adjointOptimisation/adjoint/turbulenceModels/incompressibleAdjoint/adjointRAS/adjointSpalartAllmaras/adjointSpalartAllmaras.C b/src/optimisation/adjointOptimisation/adjoint/turbulenceModels/incompressibleAdjoint/adjointRAS/adjointSpalartAllmaras/adjointSpalartAllmaras.C
index 702d5b369d3..72bf06a4887 100644
--- a/src/optimisation/adjointOptimisation/adjoint/turbulenceModels/incompressibleAdjoint/adjointRAS/adjointSpalartAllmaras/adjointSpalartAllmaras.C
+++ b/src/optimisation/adjointOptimisation/adjoint/turbulenceModels/incompressibleAdjoint/adjointRAS/adjointSpalartAllmaras/adjointSpalartAllmaras.C
@@ -725,7 +725,10 @@ tmp<fvVectorMatrix> adjointSpalartAllmaras::divDevReff(volVectorField& Ua) const
 tmp<volVectorField> adjointSpalartAllmaras::adjointMeanFlowSource()
 {
     addProfiling
-        (adjointSpalartAllmaras, "adjointSpalartAllmaras::addMomentumSource");
+    (
+        adjointSpalartAllmaras,
+        "adjointSpalartAllmaras::addMomentumSource"
+    );
     // cm formulation
     //return (- nuTilda()*fvc::grad(nuaTilda() - conservativeMomentumSource());
 
@@ -1043,7 +1046,11 @@ void adjointSpalartAllmaras::nullify()
 void adjointSpalartAllmaras::correct()
 {
     addProfiling
-        (adjointSpalartAllmaras, "adjointSpalartAllmaras::correct");
+    (
+        adjointSpalartAllmaras,
+        "adjointSpalartAllmaras::correct"
+    );
+
     if (!adjointTurbulence_)
     {
         return;
-- 
GitLab