【问题标题】:Can I expect small functions to be inlined?我可以期望内联小函数吗?
【发布时间】:2014-05-08 05:49:16
【问题描述】:

我有一个从非常大的文本字符串中提取数据的类。

在这个类中,我有很多非常简单的字符匹配。尽管有缩进、间距和 cmets,但这变得相当难以阅读。

因此,我想将这些小代码块移动到单独的函数中,这将大大提高可读性。

现在我的问题是我是否可以期望现代编译器像这样内联 5 行:

void f(page& p, size_t& index) // variable 'data' is class member
{
    p.id = 0;
    while(data[++index] != '<') {
        p.id *= 10;
        p.id += static_cast<uint>(data[index]) - 48;
    }
    index += 23;
}

父函数将运行数百万次,因此如果调用这些“sn-p”函数中的 ~7 个会增加可衡量的开销,我想确保它们被内联。

inline 关键字仍然被认为是好的做法吗?

inline void f(page& p, size_t& index);

我应该相信编译器的无限智慧吗?

【问题讨论】:

  • gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html 可能会给你更多的见解
  • 您应该信任但要验证。如果您懒得验证,那么担心它并不重要。如果您因为缺乏知识而无法验证,那么您也没有足够的知识来担心。
  • 请记住,在编程时,在证明需要更高速度之前不要过多担心优化问题,这一点很重要。函数调用开销,即使完成“数百万次”,最终也只会增加非常小的几分之一秒。您的系统是否如此重要以至于几分之一秒很重要?
  • inline 不是(只是)对编译器的提示,它具有真正的意义。
  • @marcglisse 但这个意思与inlineing 关系不大。

标签: c++ c++11 methods inline


【解决方案1】:

inline 关键字仍然被认为是好的做法吗?

在 C 和 C++ 中,函数只能在 一个 翻译单元中定义(大致相当于 .c.cpp 文件)。只有两个例外:

  • 标记为inline的函数
  • 类主体中定义的类方法(隐式认为inline then)

那个inline:表示定义是inline,与函数是否在调用点内联完全没有关系。

我应该相信编译器的无限智慧吗?

我知道这是一个“笑话”,但编译器的智慧只等于它的开发人员教给它的智慧。一般来说,你应该对你的编译器有一定的信心(毕竟你是用你的钱来信任它的),但是当谈到性能时,你需要衡量是否真的很重要.


现在,到涉及的具体功能:

  • 是的,它很可能是内联的
  • 内联它的效果取决于while 循环的平均长度,循环运行的时间越长,函数调用所涉及的开销就越少

哦,有趣的是,在 Mill CPU(仍在准备中)上,函数调用的成本与分支(因此循环运行)大致相同;因此,请记住优化是依赖于平台的,即使您强制内联(使用特定属性),您也可能会降低您未测量的平台上的性能。

【讨论】:

    【解决方案2】:

    如果您在定义原型时使用 inline 关键字,您有合理的期望内联小函数,但是取决于优化和编译开关,它可能不会(这只是内联的礼貌请求),但是您可以通过使用原型来强制它:

    inline void myInlineFunc() __attribute__((always_inline));

    这将在 gcc 中强制它内联函数。在 Visual Studio 中,可以通过以下方式完成相同的强制:

    __forceinline void myInlineFunc() __attribute__((always_inline));

    参考资料:

    gcc

    Visual Studio 2013 2012 2010 2008 2005 .net 2003

    如果这有帮助或者您需要更多信息,请告诉我:)

    【讨论】:

    • 正如其他人所说,您必须测量更改前后的速度 - 如果您不介意测量,那么您不应该打扰内联。而且你永远不知道内联实际上是让它变慢还是变快。
    • 显然,我假设问题是询问 inline 是否会保证内联问题是关于 inline 的使用,并且 OP 已经知道使用所有可能的变化来衡量结果值传递/内联/无内联等:)
    【解决方案3】:
    Is the inline keyword still considered good practice?
    

    我个人会尽可能将单体代码拆分为命名良好的内联函数。

    Should I trust the infinite wisdom of the compiler?
    

    不,请自己检查。它是否内联取决于您的编译器和您选择的选项。例如,使用 VS,您可以选择整个程序优化以及它能够自动内联任何合适的函数。在函数中弹出一个断点,启用混合代码和汇编,您应该能够查看它是否已内联。请记住,编译器可能会认为内联它不是一个好主意(例如速度/大小),如果您决定强制内联,请确保对两者进行分析以确保它实际上更快。

    【讨论】:

      【解决方案4】:

      由于您并不真正关心内联,而是关心速度,您可能会考虑让代码更快。例如,通过使其使用局部变量而不是引用,这些引用必须存储在内存中。再次,做出改变,然后测量差异。

      【讨论】:

        猜你喜欢
        • 2010-09-16
        • 1970-01-01
        • 2010-12-16
        • 2011-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多