Tuukka Turunen

Performance Improvements with Qt 5.9 LTS

Published Wednesday May 31st, 2017
10 Comments on Performance Improvements with Qt 5.9 LTS
Posted in Biz Circuit & Dev Loop, Boot time, Embedded, Graphics, Qt, Qt Quick, Releases

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.

qtquickcompilercomparison

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.

qtquickcontrolscomparison

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.

Shader Cache 

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.

shadercachecomparison

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.

qtlitecomparison

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.

Improvement in JavaScript Performance 

With the improvements in the QML engine in Qt 5.9 LTS the performance of JavaScript execution has also improved. If the Qt Quick application leverages JavaScript, there is a huge improvement in performance compared to Qt 5.6 LTS, especially on 64-bit ARM. One example of heavily leveraging JavaScript is using three.js on top of Canvas 3D, and smaller amounts of JavaScript are often used in Qt Quick applications.

javascriptcomparison

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.

qmlbench_example

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.

Conclusions

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.

Interested in taking a closer look? Qt 5.9.0 has been released today. You can get it with your online installer, from the Qt Account or from the Qt Downloads page (for open-source users).

For more details of Qt 5.9 LTS, please check the Qt 5.9 LTS release blog post.

 

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Biz Circuit & Dev Loop, Boot time, Embedded, Graphics, Qt, Qt Quick, Releases

10 comments

Markus says:

How do I pre-populate the cache? I was not able to find any documentation?

Alex Blasche Alex Blasche says:

This is done out-of-the-box at build time. There is nothing to be done from your side to enable it.

Markus says:

How does the build system know about all the QML files? Do they have to be included in the resource file or mentioned in pro-file? None of these seem to be mandatory.

Alex Blasche Alex Blasche says:

Ok, I stand corrected. There is a bit of setup to be done. Please checkout http://doc-snapshots.qt.io/qt5-5.9/qtquick-deployment.html#qml-caching-for-deployment-preview. Unfortunately the official (non-snapshot documentation) on the server is not updated yet (although it claims that it is the 5.9 version)

Leena Miettinen Leena Miettinen says:

Thanks for pointing that out! We’ll update the docs to the latest stand ASAP.

Jakub Narolewski says:

I have already asked this under the Qt 5.9 release post but maybe this is more appropriate place.
Is there a way to use qml caching using QBS build sysytem?

Patrick Stewart says:

There’s a tool called ‘qmlcachegen’ shipped with Qt which lets you generate the cache files at build time. You’ll need to add a custom rule in your build system to run that on each .qml file. However as far as I can tell it’s still necessary to ship the original QML files alongside the .qmlc files, and it only works with the files on disk, not in qresources. Does anyone know if it’s possible not to ship the .qml and/or to use qresources?

RodSeq says:

Keep up the awesome work !

Patrick Stewart says:

Is it possible to use pre-built cache files inside a qrc?

Commenting closed.

Get started today with Qt Download now