Qt 5.9 LTS improves Qt Quick and QML performance significantly, especially with Linux on ARM. We have worked hard to improve the performance in multiple areas: within the QML engine, Qt Quick graphics, QML Compiler and in the Qt Quick Controls, to name some examples. Performance has improved significantly across all areas, with some items being several times faster than with our previous long-term supported release Qt 5.6 LTS.
We are regularly running several different kinds of performance tests to see how the various optimizations work across different platforms. Some of these results are visible at testsresults.qt.io, while some tests have not been automated yet. Whenever possible, we are aiming to optimize the performance of all supported operating systems and CPU architectures. For readability and because Linux on ARM has been an area of particular focus with Qt 5.9 LTS, it is the one discussed in this post. Typically, the other platforms have received roughly similar improvements.
Qt Quick Application Startup Time
Startup time of a Qt Quick application is often critical in the embedded space. This is true for small single-process embedded systems, as well as for more complex multi-process devices. We have offered a commercial-only tool called the Qt Quick Compiler since Qt 5.3 to improve the startup time by leveraging the C++ compiler to compile QML into a normal C++ binary. Between Qt 5.6 LTS and Qt 5.9 LTS, the performance of the QML engine has improved with each new Qt release, resulting in improved application startup time. Qt 5.8 introduced QML caching, which makes second and subsequent runs of the applications to be faster. Qt 5.9 also offers a possibility to pre-populate the cache to reach improved performance already with the first run. With the Qt Quick Compiler, the first run is also already fast.
Each application has unique characteristics so the exact benefit in startup time for using Qt 5.9 LTS and/or the Qt Quick Compiler will vary. Typically, the more QML used, the bigger the improvement is. In Qt 5.9 LTS we offer two alternative options: the commercial-only Qt Quick Compiler and a new tool to populate the cache ahead-of-time, which is available for both open-source and commercial users. The performance and reduced startup time are in practice the same with both approaches in Qt 5.9 LTS.
When comparing the startup time for the same Qt Quick application with Qt 5.6 LTS without the Qt Quick Compiler to the startup time of Qt 5.9 LTS using the Qt Quick Compiler (or populated cache), the improvement is a whopping 60% on NXP i.MX6. When using the commercial-only Qt Quick Compiler of Qt 5.6 LTS the improvement in startup time is 54% (compared to Qt 5.6 LTS without the Qt Quick Compiler in use). Comparing the startup times of Qt 5.6 LTS and Qt 5.9 LTS when both are using the Qt Quick Compiler the improvement is 14% on NXP i.MX6.
The application used for the tests was the Qt Quick Controls 1 gallery and the tests were run with Linux on NXP i.MX6 and NVIDIA Tegra X1. We used the Controls 1 example because they are much heavier than Controls 2, thus better resembling a typical real-life Qt Quick application. For more measurements of Qt Quick application startup times, please check out the earlier blog post. For instructions to further optimize startup time of a Qt Quick application, please read the second post of our earlier fastboot blog series.
Qt Quick Controls Performance
Qt 5.6 LTS features Qt Quick Controls 1 while Qt 5.9 LTS features the Qt Quick Controls 2 fully supported. The main design principle of Qt Quick Controls 2 has been performance, as can be seen already from the blog post announcing them. From the very beginning, the key focus area of the new Qt Quick Controls 2 has been for embedded devices and systems. However, these can equally well be used on all supported platforms. Compared to Qt Widgets or Qt Quick Controls 1, the key difference of Qt Quick Controls 2 is that they do not adapt to platform style. We do offer multiple different styles for Qt Quick Controls 2 and it is easy to make your own style as well. From an architectural viewpoint, the key difference of Qt Quick Controls 2 is that they leverage C++ for everything that can be done with C++ and offer just the QML API for applications to use.
As illustrated in the graph above, the performance improvement is huge (note: the higher the bar, the better the performance is). We used NXP i.MX6 running Linux for the measurements. For some of the controls the performance is 14x better than before, and on average the performance has been improved 6x comparing Qt 5.9 LTS with Qt Quick Controls 2 to Qt 5.6 LTS with Qt Quick Controls 1. To benefit from the improved performance, the application needs to be ported to use Qt Quick Controls 2. This is typically quite straightforward and Qt Quick Controls 2 offers most of the common controls. Before porting, please check the documentation, as some controls, such as TableView, are not currently available with Qt Quick Controls 2.
Qt 5.9 LTS introduces a new feature to cache OpenGL shaders to disk after the first run, as explained in the blog post introducing the shader cache. If your Qt Quick application is using OpenGL shaders, which is quite often the case, it will achieve a significant improvement in startup time compared to earlier versions of Qt. When comparing the performance of Qt 5.6 LTS to Qt 5.9 LTS using the same Qt Quick application with 10 shaders, we can see a significant improvement in the initialization time of the shaders. Some of the performance improvement observed in the measurement is due to the overall improvements in the graphics performance, but most of the improvement can be attributed to the new shader cache feature.
Qt 5.9 LTS is a whopping 7x faster than Qt 5.6 LTS on startup with the same exact Qt Quick application running the same hardware. Just like the previous measurements described in the blog post, this test has also been conducted using NXP i.MX6 running Linux. The performance improvement is dependent on the hardware and especially the GPU plays a major role. Based on our measurements there are significant improvements with every piece of hardware we have tested – including ones that implement cache feature already in the OpenGL driver.
Memory Footprint Improvements
In Qt 5.8 we introduced a new configuration system and made other improvements to reduce the binary size of the Qt framework libraries used for different applications. This was developed as part of the Qt Lite project, which focused specifically on reducing the application size. With Qt 5.9 LTS we have further polished and tuned the available configurations so that more and more different kinds of applications can reach their minimal Qt configuration. Reducing the size of a Qt 5.6 LTS application is possible mainly by just using the modules needed by the application and statically linking the binary. Because of dependencies within the Qt framework, the linker is not able to reach as small binary size as it is possible with Qt 5.9 LTS using the new configuration tool.
We used a simple, but non-trivial, Qt Quick application (samegame) to compare the needed binary size of the application itself as well as all the Qt libraries it needs. With Qt 5.6 LTS the application requires 24,5MB when linking dynamically. Using static linking, the size is reduced to 13,8MB (still using Qt 5.6 LTS). Leveraging the new configuration tool in Qt 5.9 LTS and with other Qt Lite improvements, the exact same application only needs 5,4MB when static linking is used. Percentage-wise, the Qt 5.9 LTS binary size of the application is 61% smaller than the same application with Qt 5.6 LTS and static linking – without losing any functionality or making any changes to the application.
The measurements are done with v8-bench, which can be found in the qtdeclarative repository. Additional measurements are available at testresults.qt.io. With the v8-bench performance benchmark results of Qt 5.6 LTS compared to Qt 5.9 LTS, the improvement on 32-bit ARM is 16%, but on 64-bit ARM the improvement is a whopping 302% (i.e. 4x improvement). The reasons for the huge improvements are that Qt 5.9 LTS fully supports 64-bit ARM processors combined with the improvements in the QML engine.
Overall Qt Quick Performance Improvements
The examples above are just some of the highlights from many improvements we have done to the performance of Qt Quick in Qt 5.9 LTS. We have tuned multiple individual areas and optimized the execution paths within the Qt framework. It is important to note that we have also worked hard not to regress in any areas. To avoid regressions, we are regularly running a comprehensive Qt Quick benchmark suite called Qmlbench. With the Qmlbench tool we can see the performance of the most commonly used Qt Quick functionality as well as the functionality that is used less frequently. For more details, please review the thorough explanation of how we are using Qmlbench to avoid regressions.
When comparing Qt 5.6 LTS and Qt 5.9 LTS in the same environment with the comprehensive Qmlbench measurements, we can see that some areas improved up to 130% as shown in the graph above. Especially layout and complex text performance has improved drastically. The average improvement of Qt 5.9 LTS compared to Qt 5.6 LTS in all Qmlbench tests is 14% (measured on Linux). Despite which functionality is used, the improvement in performance of a Qt Quick application running Qt 5.9 LTS compared to Qt 5.6 LTS is clear and tangible for most applications.
In this blog post, I summarized some of the multiple performance improvements available with Qt 5.9 LTS. Compared to Qt 5.6 LTS, the performance of the same application running on Qt 5.9 LTS is significantly higher. Without making any changes to the application, except for compiling it for the new Qt 5.9 LTS, the performance is significantly improved. Ranging from improved application startup time and smaller footprint through to increased graphics performance, Qt 5.9 LTS is a major step forward performance-wise. Taking some of the new features, such as Qt Quick Controls 2, into use even furthers the performance improvements available with Qt 5.9 LTS.
For more details of Qt 5.9 LTS, please check the Qt 5.9 LTS release blog post.