C++静态lambda表达式的性能

6

我发现这段代码使用了C++ lambda表达式:

qreal defaultDpiScale()
{
    static qreal scale = []() {
        if (const QScreen *screen = QGuiApplication::primaryScreen())
            return screen->logicalDotsPerInchX() / 96.0;
        return 1.0;
    }();
    return scale;
}

为什么有些人会使用lambda编写此函数而不使用以下方式:

qreal defaultDpiScale()
{
    if (const QScreen *screen = QGuiApplication::primaryScreen())
        return screen->logicalDotsPerInchX() / 96.0;
    else
        return 1.0;
}

有性能优势吗?我只是想理解在这种情况下lambda的用处。


3
你知道他们做不同的事情吗? - juanchopanza
1
提示:仔细查看qreal是什么。免费提示:不,它不是double - Sam Varshavchik
3
这是一个不断重复的过程。使用lambda函数后,计算只在第一次调用函数时执行一次。如果没有lambda函数,则每次调用函数时都会执行计算。 - Sam Varshavchik
@SamVarshavchik 加上一个“ifAlreadyComputed”条件,没有分支。在我看来,这个很流畅。 - Rakurai
@PasserBy 嗯,第一次有一个分支,但是后续调用没有。抱歉,我的表述不太清楚。 - Rakurai
显示剩余2条评论
1个回答

3
qreal defaultDpiScale()
{
 // vvvv
    static qreal scale = []() {
        if (const QScreen *screen = QGuiApplication::primaryScreen())
            return screen->logicalDotsPerInchX() / 96.0;
        return 1.0;
    }();
    return scale;
}
scale是一个静态的局部变量。因此,它的初始化表达式只会执行一次。由于初始化有点复杂,作者使用了直接调用的lambda表达式,以便拥有更多的自由(例如声明变量)。
命名函数可以作为替代方案,但需要一个描述性名称(initDefaultDpiScale?),这会污染命名空间,并且需要编写更多代码,而这些代码甚至不在一个地方,而是分散在两个函数中。
每次调用函数时,您的代码都会执行一个if和(最多)3个函数调用。根据这些函数的复杂程度,这可能会对性能产生巨大的影响。此外,如果其中一个函数具有副作用,那么您的代码甚至会改变函数的行为(从其他代码可见)。
最后请注意您的代码传递的不同意图: scale是一种取决于可能变化的运行时环境的东西。而原始代码则说明scale取决于运行时环境,但在整个程序运行期间可以视为常量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接