[Interest] Can QML compiler optimize switch into array indexing?

ivan (ratijas) tkachenko me at ratijas.tk
Wed Oct 13 20:03:59 CEST 2021


Hi,
 
While working on KDE/Plasma stuff, I often encounter property bindings like
this switch-case here:
 
    enabledBorders: {
        switch (control.edge) {
        case Qt.BottomEdge:
            return PlasmaCore.FrameSvgItem.TopBorder;
        case Qt.RightEdge:
            return PlasmaCore.FrameSvgItem.LeftBorder;
        case Qt.TopEdge:
            return PlasmaCore.FrameSvgItem.BottomBorder;
        case Qt.LeftEdge:
        default:
            return PlasmaCore.FrameSvgItem.RightBorder;
        }
    }
 
To the best of my knowledge, such switches can be optimized down to a simple
array indexing. If input is not a strictly fixed enum, then an extra branch
or two is needed to clamp the value. Speaking in pseudocode:
 
    // assuming Qt.BottomEdge .. Qt.LeftEdge are sequential integers 0 .. 3
    let input = Number(control.edge); // oh no, JavaScript is dynamicly typed
    if (input < 0 || input > 3 || !Number.isInteger(input)
    ) {
        input = 3;
    }
    static const data = [
        /* [0] Qt.BottomEdge: */ PlasmaCore.FrameSvgItem.TopBorder,
        /* [1] Qt.RightEdge:  */ PlasmaCore.FrameSvgItem.LeftBorder,
        /* [2] Qt.TopEdge:    */ PlasmaCore.FrameSvgItem.BottomBorder,
        /* [3] Qt.LeftEdge:   */ PlasmaCore.FrameSvgItem.RightBorder,
    ]
    return data[input];
    
    // OR assuming binary shifts 0x00001, 0x00002, 0x00004, 0x00008
    // for small number like 0x00008, sparse array should also be good enough
    let input = Math.log2(control.edge);
    if (input < 0 || input > 3 || !Number.isInteger(input)) {
        input = 3;
    }
    static const data = [/*...same...*/];
    return data[input];
 
For bigger switches and higher bits, there's x86 instruction called TZCNT
(Count the Number of Trailing Zero Bits), which should also be much faster
than the floating point operation `Math.log2()`.
 
I've seen C/C++ compiler doing it, I've explored .NET/C# IL bytecode doing it;
but I wonder what about Qt? How do I even assess whether such optimization is
or isn't performed for QML?
 
-- 
ivan (@ratijas)




More information about the Interest mailing list