Compiling QML to C++: Annotating JavaScript functions

This is the second installment in the series on how to adjust your QML application to take the maximum advantage of qmlsc. In the first post we've set up the environment and taken an initial measurement. I highly recommend reading that one first. What we've measured was the time the updateLockButton() function in ButtonsBar.qml takes before we optimize it. It was 61.4µs for an aggregation of 8 calls, or 7.67µs for each single call on average (which is not statistically significant, but good enough for demonstration purposes).

Now, let's go back to the warning we've seen. What is qmlsc actually complaining about? It doesn't find a type annotation on the "updateLockButton" function. This means it doesn't know of what type the "locked" parameter to the function is. Therefore, it cannot compile the function to C++. Well, this is easy to fix. "locked" is obviously a boolean, and we can state this:

function updateLockButton(locked: bool) {
    lockButton.checked = !locked;
}

Let's make this change and compile and profile again the same way. Notice that the compiler warning has disappeared. Did it make a difference? On my machine the statistics now show a cumulative time of 30.1µs, with each call taking 3.76µs on average.

statistics1

Again, this is not a statistically significant measurement, but it shows how you can get a feeling for the impact of your changes.

You see a similar warning for the "logButtonChecked()" function:

Warning: ButtonsBar.qml:46:27: Could not compile function lockButtonChecked: function without type annotation returns bool of QQuickAbstractButton::checked with type bool
        return lockButton.checked;

This means the compiler wants to see a return type annotation. The function obviously returns a boolean, so this is also easy to fix:

function lockButtonChecked(): bool {
    return lockButton.checked;
}

The types you can use as annotation are QML types. They are distinct from JavaScript types. In particular, you can use value types and object types. You can explicitly specify "void" as return type in order to mark a function without arguments or return value as typed. The documentation for value types has recently been updated. You may need to look at the documentation snapshot for the latest version.

So, for example, you can have "int", "real", "vector2d", or "Rectangle" as type annotation, but not "object" or "number". "string" is a QML type as well as a JavaScript type.

A description of type annotations from the perspective of invoking the functions from C++ is also available in the documentation.

Compatibility

The fundamental concept of type annotations has been part of the language since Qt 5.14. "void" has been a builtin QML type since Qt 6.2.3.


Blog Topics:

Comments