我有一个从非常大的文本字符串中提取数据的类。
在这个课程中,我有很多非常简单的字符匹配。尽管有缩进,间距和注释,但这仍然很难阅读。
因此,我希望将这些小代码块移动到单独的函数中,这将极大地提高可读性。
现在我的问题是,如果我能期望现代编译器像这样内联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;
}
父函数将运行数百万次,因此如果调用~7个“片段”函数会增加可测量的开销,我想确保它们被内联。
inline 关键字是否仍被视为良好做法?
inline void f(page& p, size_t& index);
我应该相信编译器的无限智慧吗?
答案 0 :(得分:3)
inline
关键字是否仍被视为良好做法?
在C和C ++中,只应在一个翻译单元(大致相当于.c
或.cpp
文件)中定义一个函数。只有两个例外:
inline
inline
然后) 那是inline
:这意味着定义是inline
,并且根本不知道该函数是否会在呼叫站点内联。
我应该相信编译器的无限智慧吗?
我明白这是一个笑话&#34;但编译器的智慧只与开发人员教给它的智慧相同。一般来说,你应该对你的编译器有相对程度的信任(毕竟你用你的钱信任它),但是当谈到性能时,你需要衡量如果真的很重要
现在,涉及到具体的功能:
while
循环的平均长度,循环运行的时间越长,函数调用涉及的开销越少哦,为了好玩,在Mill CPU上(仍在准备中),函数调用与分支的成本大致相同(因此循环运行);因此,请记住优化是依赖于平台的,即使您强制内联(使用特定属性),您也可能会在未测量的平台上击落性能。
答案 1 :(得分:1)
如果在定义原型时使用inline
关键字,则可以合理地期望内联小函数,但是它可能不依赖于优化和编译开关(它只是对内联的礼貌请求),但是您可以使用如下原型强制它:
inline void myInlineFunc() __attribute__((always_inline));
gcc会强制它内联函数。在视觉工作室中,同样的强制可以通过以下方式完成:
__forceinline void myInlineFunc() __attribute__((always_inline));
<强> gcc 强>
Visual Studio 2013 2012 2010 2008 2005 .net 2003
如果有帮助或者您需要更多信息,请告诉我们。)
答案 2 :(得分:1)
Is the inline keyword still considered good practice?
就个人而言,我会尽可能将单片代码拆分为命名良好的内联函数。
Should I trust the infinite wisdom of the compiler?
不,自己检查一下。它是否内联取决于您的编译器和您选择的选项。例如,使用VS,您可以选择整个程序优化,并且可以自动内联任何合适的功能。在函数中弹出断点,启用混合代码和汇编,您应该能够看到它是否已内联。请记住,编译器可以决定内联它(例如速度/大小)不是一个好主意,如果您决定强制内联,那么请确保对两者进行分析以确保它实际上更快。
答案 3 :(得分:0)
由于您并不真正关心内联,而是关注速度,因此您可以考虑更快地编写代码。例如,通过使用局部变量而不是引用,它们必须存储在内存中。再次,进行更改然后测量差异。