Priority: P2: Important
Affects Version/s: 5.14.2, 6.3.0 RC
Component/s: QPA: Android
Commits:edd983071e (qt/qtbase/dev) edd983071e (qt/tqtc-qtbase/dev) ef6d08ac2a (qt/qtbase/6.4) ef6d08ac2a (qt/tqtc-qtbase/6.4) aa5a5c3c25 (qt/qtbase/6.3) aa5a5c3c25 (qt/tqtc-qtbase/6.3)
Please note that the bug described below probably affects Qt 6+, since code hasn't changed much.
I'm currently working on a game developed with Qt for Android, version 5.14.2. In this game, I deploy files in the assets:/ folder. Folder contains an average of 20 000 files, spread in folders containing each up to 300 files, mostly images. Overall size is ~= 200MB. In term of code, the usage is mostly using QML Images/AnimatedImages, and some QFile instances to fetch some JSON data in other files, and that's mostly it.
Testing on a very recent phone (OnePlus 9 Pro):
- Startup takes multiple seconds
- It's mostly fast, but I get some lags of ~= 100msecs from time to time when loading some assets
Testing on an older phone (Asus Zenfone 3 - old but not so bad):
- Perfs are terrible, it takes ~= 3 minutes to load the first page of the game, then loading certain assets take ~= 2min
- Once the first asset of its folder is loaded, everything from this folder looks fast, until another folder is opened
I tried not using the assets:/ folder by putting the assets in ~/Documents, and accessing images from their, and it's blazing fast with no lag for both phones.
Further readings make me see that assets:/ folder is in fact inside the APK and doesn't get extracted, meaning loading an image from the assets:/ folder is more or less unzipping a chunk of data from the APK, and that can be slow. OK, but that shouldn't be THAT slow on a phone that isn't so bad.
Multiple tests make me realize that if I put 2k files instead of 20k inside the assets:/ folder, perfs are basically improved, it takes ~= 30 sec on the older phone instead of 3 min to load. So issue is totally unrelated to the image itself, it means something is scanning the assets.
NDK profiling points to FolderIterator (see the attachment with the profiling info - this one is from the recent phone, related to the startup duration), through hard to tell who is calling it. On my side I don't do any kind of QDir::entryList(), but Qt is probably doing it under the hood. File containing FolderIterator is qtbase/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
Further researches point to this: https://bugreports.qt.io/browse/QTBUG-33704, and its patch, that built an index file at build time to prevent this issue, and that seem to have been reverted by commit c8b07f7da3ff55f92378a1e98522f318bbc43077 of qtbase (it wasn't a real revert but simply that some work was done and that part was removed). When reading https://codereview.qt-project.org/c/qt/qtbase/+/78694, it seems that it helped a lot on the cache itself, though subsequent reads would still be slow or not depending on the number of assets.
Since commit has been reverted, I guess that I'm at least facing a huge slowness related to the cache being built.
This bug seems to prevent to use assets:/ in general, unless only using something like 50 files inside.