diff --git a/python/core/auto_generated/qgsruntimeprofiler.sip.in b/python/core/auto_generated/qgsruntimeprofiler.sip.in index eae2ef30ee5b..b87065c0a280 100644 --- a/python/core/auto_generated/qgsruntimeprofiler.sip.in +++ b/python/core/auto_generated/qgsruntimeprofiler.sip.in @@ -64,11 +64,14 @@ Returns a list of all child groups with the specified ``parent``. .. versionadded:: 3.14 %End - void start( const QString &name, const QString &group = "startup" ); + void start( const QString &name, const QString &group = "startup", const QString &id = QString() ); %Docstring Start a profile event with the given name. The ``name`` of the profile event. Will have the name of the active ``group`` appended after ending. + +Since QGIS 3.34, the optional ``id`` argument can be used to provider a unique +ID to disambiguate nodes with the same ``name``. %End void end( const QString &group = "startup" ); @@ -76,10 +79,13 @@ the active ``group`` appended after ending. End the current profile event. %End - void record( const QString &name, double time, const QString &group = "startup" ); + void record( const QString &name, double time, const QString &group = "startup", const QString &id = QString() ); %Docstring Manually adds a profile event with the given name and total ``time`` (in seconds). +The optional ``id`` argument can be used to provider a unique +ID to disambiguate nodes with the same ``name``. + .. versionadded:: 3.34 %End @@ -176,12 +182,15 @@ Python scripts should not use :py:class:`QgsScopedRuntimeProfile` directly. Inst %End public: - QgsScopedRuntimeProfile( const QString &name, const QString &group = "startup" ); + QgsScopedRuntimeProfile( const QString &name, const QString &group = "startup", const QString &id = QString() ); %Docstring Constructor for QgsScopedRuntimeProfile. Automatically registers the operation in the :py:func:`QgsApplication.profiler()` instance and starts recording the run time of the operation. + +Since QGIS 3.34, the optional ``id`` argument can be used to provider a unique +ID to disambiguate nodes with the same ``name``. %End ~QgsScopedRuntimeProfile(); diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index a0f021fb6572..3e84998364d1 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -310,7 +310,7 @@ bool QgsMeshLayerRenderer::render() std::unique_ptr< QgsScopedRuntimeProfile > preparingProfile; if ( mEnableProfile ) { - profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ) ); + profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ), layerId() ); if ( mPreparationTime > 0 ) QgsApplication::profiler()->record( QObject::tr( "Create renderer" ), mPreparationTime / 1000.0, QStringLiteral( "rendering" ) ); preparingProfile = std::make_unique< QgsScopedRuntimeProfile >( QObject::tr( "Preparing render" ), QStringLiteral( "rendering" ) ); diff --git a/src/core/pointcloud/qgspointcloudlayerrenderer.cpp b/src/core/pointcloud/qgspointcloudlayerrenderer.cpp index e6ebcdf1104d..8f4bd0c29730 100644 --- a/src/core/pointcloud/qgspointcloudlayerrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudlayerrenderer.cpp @@ -83,7 +83,7 @@ bool QgsPointCloudLayerRenderer::render() std::unique_ptr< QgsScopedRuntimeProfile > profile; if ( mEnableProfile ) { - profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ) ); + profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ), layerId() ); if ( mPreparationTime > 0 ) QgsApplication::profiler()->record( QObject::tr( "Create renderer" ), mPreparationTime / 1000.0, QStringLiteral( "rendering" ) ); } diff --git a/src/core/qgsruntimeprofiler.cpp b/src/core/qgsruntimeprofiler.cpp index 6c766c786970..529126973773 100644 --- a/src/core/qgsruntimeprofiler.cpp +++ b/src/core/qgsruntimeprofiler.cpp @@ -26,8 +26,9 @@ QgsRuntimeProfiler *QgsRuntimeProfiler::sMainProfiler = nullptr; // QgsRuntimeProfilerNode // -QgsRuntimeProfilerNode::QgsRuntimeProfilerNode( const QString &group, const QString &name ) - : mName( name ) +QgsRuntimeProfilerNode::QgsRuntimeProfilerNode( const QString &group, const QString &name, const QString &id ) + : mId( id ) + , mName( name ) , mGroup( group ) { @@ -42,7 +43,10 @@ QStringList QgsRuntimeProfilerNode::fullParentPath() const { res = mParent->fullParentPath(); const QString parentName = mParent->data( Name ).toString(); - if ( !parentName.isEmpty() ) + const QString parentId = mParent->data( Id ).toString(); + if ( !parentId.isEmpty() ) + res << parentId; + else if ( !parentName.isEmpty() ) res << parentName; } return res; @@ -60,6 +64,9 @@ QVariant QgsRuntimeProfilerNode::data( int role ) const case Group: return mGroup; + case Id: + return mId; + case Elapsed: return mElapsed; @@ -92,11 +99,13 @@ int QgsRuntimeProfilerNode::indexOf( QgsRuntimeProfilerNode *child ) const return -1; } -QgsRuntimeProfilerNode *QgsRuntimeProfilerNode::child( const QString &group, const QString &name ) +QgsRuntimeProfilerNode *QgsRuntimeProfilerNode::child( const QString &group, const QString &name, const QString &id ) { for ( auto &it : mChildren ) { - if ( it->data( Group ).toString() == group && it->data( Name ).toString() == name ) + if ( it->data( Group ).toString() == group + && ( ( !id.isEmpty() && it->data( Id ) == id ) + || ( id.isEmpty() && !name.isEmpty() && it->data( Name ).toString() == name ) ) ) return it.get(); } return nullptr; @@ -203,9 +212,9 @@ QStringList QgsRuntimeProfiler::childGroups( const QString &parent, const QStrin return res; } -void QgsRuntimeProfiler::start( const QString &name, const QString &group ) +void QgsRuntimeProfiler::start( const QString &name, const QString &group, const QString &id ) { - std::unique_ptr< QgsRuntimeProfilerNode > node = std::make_unique< QgsRuntimeProfilerNode >( group, name ); + std::unique_ptr< QgsRuntimeProfilerNode > node = std::make_unique< QgsRuntimeProfilerNode >( group, name, id ); node->start(); QgsRuntimeProfilerNode *child = node.get(); @@ -226,7 +235,7 @@ void QgsRuntimeProfiler::start( const QString &name, const QString &group ) } mCurrentStack[group].push( child ); - emit started( group, child->fullParentPath(), name ); + emit started( group, child->fullParentPath(), name, id ); if ( !mGroups.contains( group ) ) { @@ -258,12 +267,12 @@ void QgsRuntimeProfiler::end( const QString &group ) parentIndex = parentIndex.parent(); } - emit ended( group, node->fullParentPath(), node->data( QgsRuntimeProfilerNode::Name ).toString(), node->data( QgsRuntimeProfilerNode::Elapsed ).toDouble() ); + emit ended( group, node->fullParentPath(), node->data( QgsRuntimeProfilerNode::Name ).toString(), node->data( QgsRuntimeProfilerNode::Id ).toString(), node->data( QgsRuntimeProfilerNode::Elapsed ).toDouble() ); } -void QgsRuntimeProfiler::record( const QString &name, double time, const QString &group ) +void QgsRuntimeProfiler::record( const QString &name, double time, const QString &group, const QString &id ) { - std::unique_ptr< QgsRuntimeProfilerNode > node = std::make_unique< QgsRuntimeProfilerNode >( group, name ); + std::unique_ptr< QgsRuntimeProfilerNode > node = std::make_unique< QgsRuntimeProfilerNode >( group, name, id ); QgsRuntimeProfilerNode *child = node.get(); if ( !mCurrentStack[ group ].empty() ) @@ -282,9 +291,9 @@ void QgsRuntimeProfiler::record( const QString &name, double time, const QString endInsertRows(); } - emit started( group, child->fullParentPath(), name ); + emit started( group, child->fullParentPath(), name, id ); child->setElapsed( time ); - emit ended( group, child->fullParentPath(), child->data( QgsRuntimeProfilerNode::Name ).toString(), child->data( QgsRuntimeProfilerNode::Elapsed ).toDouble() ); + emit ended( group, child->fullParentPath(), child->data( QgsRuntimeProfilerNode::Name ).toString(), child->data( QgsRuntimeProfilerNode::Id ).toString(), child->data( QgsRuntimeProfilerNode::Elapsed ).toDouble() ); if ( !mGroups.contains( group ) ) { @@ -443,12 +452,16 @@ QVariant QgsRuntimeProfiler::headerData( int section, Qt::Orientation orientatio } } -void QgsRuntimeProfiler::otherProfilerStarted( const QString &group, const QStringList &path, const QString &name ) +void QgsRuntimeProfiler::otherProfilerStarted( const QString &group, const QStringList &path, const QString &name, const QString &id ) { QgsRuntimeProfilerNode *parentNode = mRootNode.get(); for ( const QString &part : path ) { - QgsRuntimeProfilerNode *child = parentNode->child( group, part ); + // part may be name or id. Prefer checking it as id + QgsRuntimeProfilerNode *child = parentNode->child( group, QString(), part ); + if ( !child ) + child = parentNode->child( group, part ); + if ( !child ) { std::unique_ptr< QgsRuntimeProfilerNode > newChild = std::make_unique< QgsRuntimeProfilerNode >( group, part ); @@ -466,12 +479,12 @@ void QgsRuntimeProfiler::otherProfilerStarted( const QString &group, const QStri } } - if ( parentNode->child( group, name ) ) + if ( parentNode->child( group, name, id ) ) return; const QModelIndex parentIndex = node2index( parentNode ); beginInsertRows( parentIndex, parentNode->childCount(), parentNode->childCount() ); - parentNode->addChild( std::make_unique< QgsRuntimeProfilerNode >( group, name ) ); + parentNode->addChild( std::make_unique< QgsRuntimeProfilerNode >( group, name, id ) ); endInsertRows(); if ( !mGroups.contains( group ) ) @@ -481,12 +494,16 @@ void QgsRuntimeProfiler::otherProfilerStarted( const QString &group, const QStri } } -void QgsRuntimeProfiler::otherProfilerEnded( const QString &group, const QStringList &path, const QString &name, double elapsed ) +void QgsRuntimeProfiler::otherProfilerEnded( const QString &group, const QStringList &path, const QString &name, const QString &id, double elapsed ) { QgsRuntimeProfilerNode *parentNode = mRootNode.get(); for ( const QString &part : path ) { - QgsRuntimeProfilerNode *child = parentNode->child( group, part ); + // part may be name or id. Prefer checking it as id + QgsRuntimeProfilerNode *child = parentNode->child( group, QString(), part ); + if ( !child ) + child = parentNode->child( group, part ); + if ( !child ) { std::unique_ptr< QgsRuntimeProfilerNode > newChild = std::make_unique< QgsRuntimeProfilerNode >( group, part ); @@ -504,10 +521,10 @@ void QgsRuntimeProfiler::otherProfilerEnded( const QString &group, const QString } } - QgsRuntimeProfilerNode *destNode = parentNode->child( group, name ); + QgsRuntimeProfilerNode *destNode = parentNode->child( group, name, id ); if ( !destNode ) { - std::unique_ptr< QgsRuntimeProfilerNode > node = std::make_unique< QgsRuntimeProfilerNode >( group, name ); + std::unique_ptr< QgsRuntimeProfilerNode > node = std::make_unique< QgsRuntimeProfilerNode >( group, name, id ); destNode = node.get(); const QModelIndex parentIndex = node2index( parentNode ); beginInsertRows( parentIndex, parentNode->childCount(), parentNode->childCount() ); @@ -554,7 +571,12 @@ QgsRuntimeProfilerNode *QgsRuntimeProfiler::pathToNode( const QString &group, co if ( part.isEmpty() ) continue; - res = res->child( group, part ); + // part may be name or id. Prefer checking it as id + QgsRuntimeProfilerNode *child = res->child( group, QString(), part ); + if ( !child ) + child = res->child( group, part ); + + res = child; if ( !res ) break; } @@ -566,7 +588,12 @@ QgsRuntimeProfilerNode *QgsRuntimeProfiler::pathToNode( const QString &group, co QgsRuntimeProfilerNode *res = mRootNode.get(); for ( const QString &part : path ) { - res = res->child( group, part ); + // part may be name or id. Prefer checking it as id + QgsRuntimeProfilerNode *child = res->child( group, QString(), part ); + if ( !child ) + child = res->child( group, part ); + + res = child; if ( !res ) break; } @@ -648,10 +675,10 @@ QString QgsRuntimeProfiler::asText( const QString &group ) // QgsScopedRuntimeProfile // -QgsScopedRuntimeProfile::QgsScopedRuntimeProfile( const QString &name, const QString &group ) +QgsScopedRuntimeProfile::QgsScopedRuntimeProfile( const QString &name, const QString &group, const QString &id ) : mGroup( group ) { - QgsApplication::profiler()->start( name, mGroup ); + QgsApplication::profiler()->start( name, mGroup, id ); } QgsScopedRuntimeProfile::~QgsScopedRuntimeProfile() diff --git a/src/core/qgsruntimeprofiler.h b/src/core/qgsruntimeprofiler.h index 96d41b2fee8d..cc2578f2de7a 100644 --- a/src/core/qgsruntimeprofiler.h +++ b/src/core/qgsruntimeprofiler.h @@ -47,12 +47,15 @@ class CORE_EXPORT QgsRuntimeProfilerNode Group, //!< Node group Elapsed, //!< Node elapsed time ParentElapsed, //!< Total elapsed time for node's parent + Id, //!< Internal node ID (since QGIS 3.34) }; /** * Constructor for QgsRuntimeProfilerNode, with the specified \a group and \a name. + * + * Since QGIS 3.34 an internal \a id can be specified to disambiguate entries with duplicate names. */ - QgsRuntimeProfilerNode( const QString &group, const QString &name ); + QgsRuntimeProfilerNode( const QString &group, const QString &name, const QString &id = QString() ); //! QgsRuntimeProfilerNode cannot be copied QgsRuntimeProfilerNode( const QgsRuntimeProfilerNode &other ) = delete; @@ -70,6 +73,8 @@ class CORE_EXPORT QgsRuntimeProfilerNode /** * Returns the full path to the node's parent. + * + * This will contain node IDs if set, otherwise node names. */ QStringList fullParentPath() const; @@ -96,10 +101,10 @@ class CORE_EXPORT QgsRuntimeProfilerNode int indexOf( QgsRuntimeProfilerNode *child ) const; /** - * Finds the child with matching \a group and \a name. Returns NULLPTR if + * Finds the child with matching \a group, \a name and \a id (since QGIS 3.34). Returns NULLPTR if * a matching child was not found. */ - QgsRuntimeProfilerNode *child( const QString &group, const QString &name ); + QgsRuntimeProfilerNode *child( const QString &group, const QString &name, const QString &id = QString() ); /** * Returns the child at the specified \a index. @@ -151,6 +156,7 @@ class CORE_EXPORT QgsRuntimeProfilerNode QElapsedTimer mProfileTime; double mElapsed = 0; + QString mId; QString mName; QString mGroup; @@ -211,8 +217,11 @@ class CORE_EXPORT QgsRuntimeProfiler : public QAbstractItemModel * \brief Start a profile event with the given name. * The \a name of the profile event. Will have the name of * the active \a group appended after ending. + * + * Since QGIS 3.34, the optional \a id argument can be used to provider a unique + * ID to disambiguate nodes with the same \a name. */ - void start( const QString &name, const QString &group = "startup" ); + void start( const QString &name, const QString &group = "startup", const QString &id = QString() ); /** * \brief End the current profile event. @@ -222,9 +231,12 @@ class CORE_EXPORT QgsRuntimeProfiler : public QAbstractItemModel /** * Manually adds a profile event with the given name and total \a time (in seconds). * + * The optional \a id argument can be used to provider a unique + * ID to disambiguate nodes with the same \a name. + * * \since QGIS 3.34 */ - void record( const QString &name, double time, const QString &group = "startup" ); + void record( const QString &name, double time, const QString &group = "startup", const QString &id = QString() ); /** * Returns the profile time for the specified \a name. @@ -281,8 +293,8 @@ class CORE_EXPORT QgsRuntimeProfiler : public QAbstractItemModel ///@cond PRIVATE signals: - void started( const QString &group, const QStringList &path, const QString &name ); - void ended( const QString &group, const QStringList &path, const QString &name, double elapsed ); + void started( const QString &group, const QStringList &path, const QString &name, const QString &id ); + void ended( const QString &group, const QStringList &path, const QString &name, const QString &id, double elapsed ); ///@endcond #endif @@ -293,8 +305,8 @@ class CORE_EXPORT QgsRuntimeProfiler : public QAbstractItemModel private slots: - void otherProfilerStarted( const QString &group, const QStringList &path, const QString &name ); - void otherProfilerEnded( const QString &group, const QStringList &path, const QString &name, double elapsed ); + void otherProfilerStarted( const QString &group, const QStringList &path, const QString &name, const QString &id ); + void otherProfilerEnded( const QString &group, const QStringList &path, const QString &name, const QString &id, double elapsed ); private: @@ -348,8 +360,11 @@ class CORE_EXPORT QgsScopedRuntimeProfile * * Automatically registers the operation in the QgsApplication::profiler() instance * and starts recording the run time of the operation. + * + * Since QGIS 3.34, the optional \a id argument can be used to provider a unique + * ID to disambiguate nodes with the same \a name. */ - QgsScopedRuntimeProfile( const QString &name, const QString &group = "startup" ); + QgsScopedRuntimeProfile( const QString &name, const QString &group = "startup", const QString &id = QString() ); /** * Records the final runtime of the operation in the profiler instance. diff --git a/src/core/raster/qgsrasterlayerrenderer.cpp b/src/core/raster/qgsrasterlayerrenderer.cpp index 0e6faf965356..944f77d76c26 100644 --- a/src/core/raster/qgsrasterlayerrenderer.cpp +++ b/src/core/raster/qgsrasterlayerrenderer.cpp @@ -326,7 +326,7 @@ bool QgsRasterLayerRenderer::render() std::unique_ptr< QgsScopedRuntimeProfile > profile; if ( mEnableProfile ) { - profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ) ); + profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ), layerId() ); if ( mPreparationTime > 0 ) QgsApplication::profiler()->record( QObject::tr( "Create renderer" ), mPreparationTime / 1000.0, QStringLiteral( "rendering" ) ); } diff --git a/src/core/tiledscene/qgstiledscenelayerrenderer.cpp b/src/core/tiledscene/qgstiledscenelayerrenderer.cpp index 8d2d4dc80520..9b57fe960f46 100644 --- a/src/core/tiledscene/qgstiledscenelayerrenderer.cpp +++ b/src/core/tiledscene/qgstiledscenelayerrenderer.cpp @@ -78,7 +78,7 @@ bool QgsTiledSceneLayerRenderer::render() std::unique_ptr< QgsScopedRuntimeProfile > profile; if ( mEnableProfile ) { - profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ) ); + profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ), layerId() ); if ( mPreparationTime > 0 ) QgsApplication::profiler()->record( QObject::tr( "Create renderer" ), mPreparationTime / 1000.0, QStringLiteral( "rendering" ) ); } diff --git a/src/core/vector/qgsvectorlayerrenderer.cpp b/src/core/vector/qgsvectorlayerrenderer.cpp index d4e9bc9da586..c9f082bf905f 100644 --- a/src/core/vector/qgsvectorlayerrenderer.cpp +++ b/src/core/vector/qgsvectorlayerrenderer.cpp @@ -244,7 +244,7 @@ bool QgsVectorLayerRenderer::render() std::unique_ptr< QgsScopedRuntimeProfile > profile; if ( mEnableProfile ) { - profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ) ); + profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ), layerId() ); if ( mPreparationTime > 0 ) QgsApplication::profiler()->record( QObject::tr( "Create renderer" ), mPreparationTime / 1000.0, QStringLiteral( "rendering" ) ); } diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index 3102a195c095..708671ed7437 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -75,7 +75,7 @@ bool QgsVectorTileLayerRenderer::render() std::unique_ptr< QgsScopedRuntimeProfile > profile; if ( mEnableProfile ) { - profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ) ); + profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( "rendering" ), layerId() ); if ( mPreparationTime > 0 ) QgsApplication::profiler()->record( QObject::tr( "Create renderer" ), mPreparationTime / 1000.0, QStringLiteral( "rendering" ) ); }