6.3.1.SMART BEAR AQ Time

1.Introduction

  • AQtime is a performance profiler and memory/resource debugging toolset developed by SmartBear Software. It is integrated into Microsoft Visual Studio, Visual Studio Test Projects and Embarcadero RAD Studio[4] that allows analyzing the application without leaving the development environment (source: wiki)

2.Profiling

  • 1.Install AQ Time Software

  • 2.Create a AQ Time Project

    • Right click on solution and select Add -> New Project

  • 3.Set profiling target output file

    • On Setup page of AQ Time Project, right click on left side bar and select Add Output

  • 4.Start profiling

    • Select AQtime->Run from menu bar, then the target output file you set before will be launched, do the action what you want to profile

  • 5.Get result

    • 1.Click Get results you can get a report from start to present

      • Time

      • Time with Children

      • Hot Count

    • 2.Click one function that you would like to know the detail, you can click Panel List -> Call Graph

    • 3.Finally, you can get some information such as: Code Type, Hit Count, Time, Time with Children for selected function and children function

3.Filtering less relevant functions

  • In order to find out the performance bottleneck, we can exclude some sections or functions if they are not part of your

4.Optimize performance

  • 1.Found the performance bottleneck from report and graph which AQ time generated

  • 2.For example, I find that DoNavigationLineOverlapCheck() was the performance bottleneck, check it's children by checking graph

  • 3.The constructor of LaneLineInfo will be called many time because we create new LaneLineInfo Objects in for loop

LanelineList NavigationSplineOverlapCheck::CheckAndGetFailedLines(
    const LanelineList& aLanelineList,
    int* aTotalCheck /*= nullptr*/)
{
    static const double aNavigationLineWidth = FileData::GetConfigReader()->GetNavigationLineWidth();

    LanelineList failedLineList;
    if (aTotalCheck != nullptr)
    {
        *aTotalCheck = 0;
    }
    bool checkFlag = false;
    int laneLineSize = aLanelineList.size();
    for(int i = 0 ; i < laneLineSize; i++)
    {
        checkFlag = false;
        LanelineInfo outerLane = aLanelineList[i];
        for(int j = i + 1 ; j < laneLineSize; j++)
        {
            LanelineInfo innerLane = aLanelineList[j];
            if( innerLane._fromLane._line2DId == outerLane._fromLane._line2DId &&
                innerLane._toLane._line2DId == outerLane._toLane._line2DId)
            {
                ...
  • 4.To optimize the performance of this function and also maintain readability, using const reference was a good choice in this case

LanelineList NavigationSplineOverlapCheck::CheckAndGetFailedLines(
    const LanelineList& aLanelineList,
    int* aTotalCheck /*= nullptr*/)
{
    static const double aNavigationLineWidth = FileData::GetConfigReader()->GetNavigationLineWidth();

    LanelineList failedLineList;
    if (aTotalCheck != nullptr)
    {
        *aTotalCheck = 0;
    }
    bool checkFlag = false;
    int laneLineSize = aLanelineList.size();
    for(int i = 0 ; i < laneLineSize; i++)
    {
        checkFlag = false;
        const LanelineInfo& outerLane = aLanelineList[i];
        for(int j = i + 1 ; j < laneLineSize; j++)
        {
            const LanelineInfo& innerLane = aLanelineList[j];
            if( innerLane._fromLane._line2DId == outerLane._fromLane._line2DId &&
                innerLane._toLane._line2DId == outerLane._toLane._line2DId)
            {
                ...
  • 5.Check the graph again after we modify the code, the change optimize the performance for sure according to the latest time cost of LaneLineInfo is smaller than before

Last updated