20

Is QML translated into native code at the compilation time or is it interpreted at runtime almost the way JavaScript is ran in a web browser?

Ivan
  • 63,011
  • 101
  • 250
  • 382
  • JavaScript in the web browser is rarely compiled. Usually it is compiled just-in-time (JIT). –  Feb 25 '12 at 22:02

5 Answers5

6

AFAIK, there seem to be no straight and detailed explanation in the Qt documentation, but some Qt hackers try to explain it:

QML is compiled to an optimized bytecode-like stream and the JavaScript expressions pass through an optimized evaluator for simple expressions.

There also is related QTBUG task QtQuick startup time needs to be improved; cache compiled QML between runs

My understanding is that QML status hasn't been settled completely and engineers don't declare it fixed, so they have freedom to improve it in future.

ATM, it best advice is to mix C++ with QML, having all application logic in C++ and presentation in QML, but ideally divided into smaller QML files, not in a single large QML file.

mloskot
  • 37,086
  • 11
  • 109
  • 136
4

With Qt 5.3 and an enterprise license, there is actually a way to have it precompiled.

https://doc.qt.io/QtQuickCompiler/

This is useful for iOS where Apple doesn't allow JIT code generation.

tanius
  • 14,003
  • 3
  • 51
  • 63
guruz
  • 1,604
  • 14
  • 21
  • As per the linked document, no enterprise license is necessary anymore because Qt Quick Compiler became part of the regular Qt Quick module since Qt 5.11. – tanius Jun 15 '20 at 16:15
4

I just had the same question, and here is what the situation looks now, a few years down the road:

Current situation (Qt 5.15)

The most advanced technique in Qt 5 is using ahead-of-time QML compilation. This uses QuickCompiler, a tool that was "Introduced in Qt 5.3 for commercial licensees, both commercial and open source in Qt 5.11" (source). From an older documentation of QtQuickCompiler it becomes more clear what it actually does:

[Without QtQuickCompiler the] popular Just-in-time (JIT) compilation technique is used to generate machine code on the fly [from QML], which speeds up the execution of JavaScript and QML binding expressions.

Unfortunately this approach has some disadvantages: […] some platform versions such as iOS or Windows RT do not permit the dynamic generation of machine code. […]

Compiled Qt Quick [via QtQuickCompiler] is an elegant solution to these problems: .qml files as well as accompanying .js files can be translated into intermediate C++ source code. After compilation with a traditional compiler, the code is linked into the application binary.

This ahead-of-time compilation with QtQuickCompiler produces the same bytecode that just-in-time (JIT) compilation would otherwise produce at runtime from QML. QtQuickCompiler indeed produces "intermediate C++ source code", but that is simply bytecode in C++ data structures, to be embedded into the resulting C++ executable. I tested it; to see it for yourself, you just have to build a Qt Quick project with QtQuickCompiler enabled, and then open file {filename}_qml.cpp in your build directory, which has been generated for your {filename}.qml. It will look like this:

// /{filename}.qml
namespace QmlCacheGeneratedCode {
    namespace _0x5f__main_qml {
        extern const unsigned char qmlData alignas(16) [] = {
            0x71,0x76,0x34,0x63,0x64,0x61,0x74,0x61,
            0x20,0x0,0x0,0x0,0x4,0xc,0x5,0x0,
            // … many many more lines …
            0x40,0x0,0x40,0x1,0x40,0x0,0xf0,0x1,
            0x0,0x0,0x0,0x0
        };
    }
}

So in Qt 5, QML is neither translated into native [C++] code at compilation time, nor interpreted at runtime. It is instead compiled ahead-of-time to bytecode. This bytecode will then be run in a small virtual machine for JavaScript, similar to what is done with Java bytecode in the JVM. A virtual machine is always needed because compiling machine code from a weakly typed language like QML / JavaScript is not possible.

When neither QtQuickCompiler nor JIT compilation with caching is available, "QML provides an interpreter to allow for the full use of QML, but it comes at the expense of a longer execution time." (source)

Future situation (Qt 6)

It is planned that the future release of Qt 6 will indeed include the translation of QML into native C++ code, which is then compiled just as any other C++ code:

Support compiling QML to efficient C++ and native code. With strong typing and simpler lookup rules we can convert QML to efficient C++ and native code, significantly increasing runtime performance. (source)

I have to say, that sounds great :)

tanius
  • 14,003
  • 3
  • 51
  • 63
1

There's a big difference between compiled languages and interpreted languages. A QML document is interpreted by the QML runtime. In a sense, you can say that it is executed like JavaScript.

The QML runtime includes a QML engine, JavaScript engine, and mechanism to bind to the Qt Framework.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
0

Qt Quick Compiler™ with Qt 6.3

The new Qt Quick Compiler will consist of two components: the QML Type Compiler and QML Script Compiler. The QML Type Compiler will compile QML object structures into C++ classes. The QML Script Compiler will compile functions and expressions in QML files of an application into C++ code. As much as possible, since there will be some limits set by the nature of JavaScript. If certain statements cannot be compiled, regular interpretation and caching will be used..... (Source)

Jeet
  • 1,006
  • 1
  • 14
  • 25