What exactly is QIcon::cacheKey based on?
-
I have a cache of icons in my application. Naturally, I use
QIcon::cacheKey
. And I'm starting to suspect it doesn't do what I think it should. There are like 20-50 different icons, and yet mymap<QIcon::cacheKey, QIcon>
has 3000 entries. It's as if the hash (cacheKey) is based on the Pixmap object (which I've got a new one for every icon), rather than the actual image data.
Consequently, what is the fastest way to obtain an image-data-based hash for caching QIcons? This part of the application is already underperforming, so hashing must be fast. -
Hi,
It's not based on either, You should take a look at QIcon's implementation for the current algorithm used.
How are you adding these icons to your cache ?
-
Yep, it definitely doesn't do what I thought it would.
I'm requesting the icons usingQFileIconProvider
, and simply add them to the map:QIcon icon = _provider.icon(filePath);
_cahce[icon.cacheKey()] = icon;
If 2 different files have the same icon, which is very common, the icons I get will have the same image, but still different key - because it's not based on the contents.
-
This works, but I wonder if it's the fastest way.
QCryptographicHash qCryptoHash(QCryptographicHash::Md5);
const auto qimage = icon.pixmap(icon.availableSizes().front()).toImage();
qCryptoHash.addData((const char*)qimage.constBits(), qimage.bytesPerLine() * qimage.height());
const auto result = qCryptoHash.result();
const qulonglong iconHash = *(qulonglong*)(result.data()) ^ *(qulonglong*)(result.data()+8);
-
No it's not, but since it should only be done once that might be enough
-
No, it's not done once. I take hash of a QIcon every time I need to look it up in the cache. Basically, I'm calculating hashes all the time.
How can I optimize the code? -
Why not keep it with the icon after calculating at construction time ?
How are you using that cache ? It sounds strange that you get 3000 different entries.
-
I no longer have 3000 entries after introducing the hash function that accounts for the image content.
I can't calculate the hash any less often because I'm getting new and new icons from QFileIconProvider, and I need to hash their contents to find out if I already have this icon in the cache.