Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. First call to QIcon::pixmap takes 180 milliseconds
Forum Updated to NodeBB v4.3 + New Features

First call to QIcon::pixmap takes 180 milliseconds

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 582 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Youda008Y Offline
    Youda008Y Offline
    Youda008
    wrote on last edited by
    #1

    I have a custom list view and model displaying user-specified filesystem entries (both files and directories are possible).

    I wanted it to start displaying icons the OS uses for those filesystem entries, so i added this method, that is called from Model::data( role = Qt::DecorationRole )

    static QHash< QString, QIcon > g_filesystemIconCache;
    
    const QIcon & Entry::getIcon() const
    {
        static QFileIconProvider iconProvider;  // only one initialization needed
    
        auto iter = g_filesystemIconCache.find( this->path );
        if (iter == g_filesystemIconCache.end())
        {
            iter = g_filesystemIconCache.insert( this->path, iconProvider.icon( entryInfo ) );
        }
        return iter.value();
    }
    

    But soon i noticed my application loading time has increased noticably.
    My first idea was that it is caused by the high-res icons used by Windows, so i modified the inner code block creating the icon to

            QIcon origIcon = iconProvider.icon( this->path );
            QSize smallestSize = origIcon.availableSizes()[0];
            QPixmap pixmap = origIcon.pixmap( smallestSize );
            iter = g_filesystemIconCache.insert( this->path, QIcon( pixmap ) );
    

    and measured the time it took for each line and found out that the origIcon.pixmap( smallestSize ) took 180ms for the first item and then less than 1ms for the rest of items.

    This only happens on Windows and it only happens with the icons provided by QFileIconProvider. If i load an internal resource icon instead, the total icon loading time is few milliseconds.

    Do you know what is causing QIcon::pixmap to take so long and is there a workaround?

    Christian EhrlicherC 1 Reply Last reply
    0
    • Youda008Y Youda008

      I have a custom list view and model displaying user-specified filesystem entries (both files and directories are possible).

      I wanted it to start displaying icons the OS uses for those filesystem entries, so i added this method, that is called from Model::data( role = Qt::DecorationRole )

      static QHash< QString, QIcon > g_filesystemIconCache;
      
      const QIcon & Entry::getIcon() const
      {
          static QFileIconProvider iconProvider;  // only one initialization needed
      
          auto iter = g_filesystemIconCache.find( this->path );
          if (iter == g_filesystemIconCache.end())
          {
              iter = g_filesystemIconCache.insert( this->path, iconProvider.icon( entryInfo ) );
          }
          return iter.value();
      }
      

      But soon i noticed my application loading time has increased noticably.
      My first idea was that it is caused by the high-res icons used by Windows, so i modified the inner code block creating the icon to

              QIcon origIcon = iconProvider.icon( this->path );
              QSize smallestSize = origIcon.availableSizes()[0];
              QPixmap pixmap = origIcon.pixmap( smallestSize );
              iter = g_filesystemIconCache.insert( this->path, QIcon( pixmap ) );
      

      and measured the time it took for each line and found out that the origIcon.pixmap( smallestSize ) took 180ms for the first item and then less than 1ms for the rest of items.

      This only happens on Windows and it only happens with the icons provided by QFileIconProvider. If i load an internal resource icon instead, the total icon loading time is few milliseconds.

      Do you know what is causing QIcon::pixmap to take so long and is there a workaround?

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      What exact Qt and Windows version do you use? Please provide a minimal, compilable example to reproduce your issue.
      @Axel-Spoerl: Looks similar to QTBUG-110416 ?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      Youda008Y 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        What exact Qt and Windows version do you use? Please provide a minimal, compilable example to reproduce your issue.
        @Axel-Spoerl: Looks similar to QTBUG-110416 ?

        Youda008Y Offline
        Youda008Y Offline
        Youda008
        wrote on last edited by
        #3

        @Christian-Ehrlicher

        Ok, here it is.

        OS: Windows 10 Pro 22H2 19045.3086
        Qt: 5.15.7

        Minimal example: IconList.zip

        Axel SpoerlA 1 Reply Last reply
        0
        • Youda008Y Youda008

          @Christian-Ehrlicher

          Ok, here it is.

          OS: Windows 10 Pro 22H2 19045.3086
          Qt: 5.15.7

          Minimal example: IconList.zip

          Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote on last edited by Axel Spoerl
          #4

          @Youda008
          Good morning,
          just ran the reproducer locally on Qt 5.15.14 and the latest bleeding edge (6.7 dev), both developer builds in debug mode.
          The codebase of QFileIconProviderhasn't seen many changes and the stats don't show a big difference.
          I use laptop computer, which is not incredibly fast. But it's got a fast SSD drive.
          I don't want to exclude the possibility of a bug in Qt. However, if only the first call takes forever, I would find it worth checking for a local file caching issue.
          I'd also consider changing to Qt 6 (in which case one line of code needs to be adapted, because QFileIconProvider::icon() doesn't like string arguments any more. Just call iconProvider.icon(entry);).
          Cheers
          Axel

          08:16:45: Debugging /home/axel/QtDev/build-IconList-Qt_6_7_0_dev_build/Debug/IconList ...
          #0 : QDirIterator::next()        took   0ms
          #1 : QFileIconProvider::icon()   took  61ms
          #2 : QIcon::pixmap()             took   0ms
          #3 : QIcon::QIcon( QPixmap & )   took   0ms
          08:17:00: Debugging of /home/axel/QtDev/build-IconList-Qt_6_7_0_dev_build/Debug/IconList has finished with exit code 0.
          
          08:21:13: Debugging /home/axel/QtDev/build-IconList-Qt_5_15_14_dev_build/Debug/IconList ...
          #0 : QDirIterator::next()        took   0ms
          #1 : QFileIconProvider::icon()   took  79ms
          #2 : QIcon::pixmap()             took   0ms
          #3 : QIcon::QIcon( QPixmap & )   took   0ms
          08:21:29: Debugging of /home/axel/QtDev/build-IconList-Qt_5_15_14_dev_build/Debug/IconList has finished with exit code 0.
          

          Software Engineer
          The Qt Company, Oslo

          Youda008Y 1 Reply Last reply
          1
          • Axel SpoerlA Axel Spoerl

            @Youda008
            Good morning,
            just ran the reproducer locally on Qt 5.15.14 and the latest bleeding edge (6.7 dev), both developer builds in debug mode.
            The codebase of QFileIconProviderhasn't seen many changes and the stats don't show a big difference.
            I use laptop computer, which is not incredibly fast. But it's got a fast SSD drive.
            I don't want to exclude the possibility of a bug in Qt. However, if only the first call takes forever, I would find it worth checking for a local file caching issue.
            I'd also consider changing to Qt 6 (in which case one line of code needs to be adapted, because QFileIconProvider::icon() doesn't like string arguments any more. Just call iconProvider.icon(entry);).
            Cheers
            Axel

            08:16:45: Debugging /home/axel/QtDev/build-IconList-Qt_6_7_0_dev_build/Debug/IconList ...
            #0 : QDirIterator::next()        took   0ms
            #1 : QFileIconProvider::icon()   took  61ms
            #2 : QIcon::pixmap()             took   0ms
            #3 : QIcon::QIcon( QPixmap & )   took   0ms
            08:17:00: Debugging of /home/axel/QtDev/build-IconList-Qt_6_7_0_dev_build/Debug/IconList has finished with exit code 0.
            
            08:21:13: Debugging /home/axel/QtDev/build-IconList-Qt_5_15_14_dev_build/Debug/IconList ...
            #0 : QDirIterator::next()        took   0ms
            #1 : QFileIconProvider::icon()   took  79ms
            #2 : QIcon::pixmap()             took   0ms
            #3 : QIcon::QIcon( QPixmap & )   took   0ms
            08:21:29: Debugging of /home/axel/QtDev/build-IconList-Qt_5_15_14_dev_build/Debug/IconList has finished with exit code 0.
            
            Youda008Y Offline
            Youda008Y Offline
            Youda008
            wrote on last edited by Youda008
            #5

            @Axel-Spoerl Thank you for looking into it.

            Interestingly, in your results it's the QFileIconProvider::icon() that takes the most time, while in my tests it's the QIcon::pixmap().

            #0 : QDirIterator::next()        took   0ms
            #1 : QFileIconProvider::icon()   took   0ms
            #2 : QIcon::pixmap()             took 179ms
            #3 : QIcon::QIcon( QPixmap & )   took   0ms
            #4 : QDirIterator::next()        took   1ms
            #5 : QFileIconProvider::icon()   took   0ms
            #6 : QIcon::pixmap()             took  12ms
            #7 : QIcon::QIcon( QPixmap & )   took   0ms
            #8 : QDirIterator::next()        took   0ms
            #9 : QFileIconProvider::icon()   took   0ms
            #10: QIcon::pixmap()             took  11ms
            #11: QIcon::QIcon( QPixmap & )   took   0ms
            

            It looks to me as if the QFileIconProvider::icon() or QIcon::pixmap() performed some heavy on-demand initialization. I am wondering what that could be and if it can be prevented.

            Can you please add more files to the directory of the executable from which the code loads the icons, so that we can see what happens with the consequent calls?
            Your time might not be as large as mine, but you might still see the same big difference between the first call and the other calls.

            In the meantime i will try to investiate with ProcessMonitor, because i cannot debug the Qt's code, because i use pre-built packages.

            Christian EhrlicherC 1 Reply Last reply
            0
            • Youda008Y Youda008

              @Axel-Spoerl Thank you for looking into it.

              Interestingly, in your results it's the QFileIconProvider::icon() that takes the most time, while in my tests it's the QIcon::pixmap().

              #0 : QDirIterator::next()        took   0ms
              #1 : QFileIconProvider::icon()   took   0ms
              #2 : QIcon::pixmap()             took 179ms
              #3 : QIcon::QIcon( QPixmap & )   took   0ms
              #4 : QDirIterator::next()        took   1ms
              #5 : QFileIconProvider::icon()   took   0ms
              #6 : QIcon::pixmap()             took  12ms
              #7 : QIcon::QIcon( QPixmap & )   took   0ms
              #8 : QDirIterator::next()        took   0ms
              #9 : QFileIconProvider::icon()   took   0ms
              #10: QIcon::pixmap()             took  11ms
              #11: QIcon::QIcon( QPixmap & )   took   0ms
              

              It looks to me as if the QFileIconProvider::icon() or QIcon::pixmap() performed some heavy on-demand initialization. I am wondering what that could be and if it can be prevented.

              Can you please add more files to the directory of the executable from which the code loads the icons, so that we can see what happens with the consequent calls?
              Your time might not be as large as mine, but you might still see the same big difference between the first call and the other calls.

              In the meantime i will try to investiate with ProcessMonitor, because i cannot debug the Qt's code, because i use pre-built packages.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Youda008 said in First call to QIcon::pixmap takes 180 milliseconds:

              e Qt's code, because i use pre-built packages.

              But even there you can install the debug symbols and sources.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              0
              • Youda008Y Offline
                Youda008Y Offline
                Youda008
                wrote on last edited by Youda008
                #7

                It seems to be DLL loading. Apparently when Windows is asked to provide the file icons, it starts loading a crapton of DLLs related to icons and thumbnails, and if the OS or drive is not in the best shape, it takes long time.
                Logfile.png

                1 Reply Last reply
                2

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved