定义一个调用其他函数的内联函数是否有意义?
Does it makes sense to define an inline function which makes calls to other function(s)?
据我所知,内联函数是一种增强性能的优化,因此它应该 运行 与宏一样快。内联函数的代码尽量短
我想知道在内联函数中嵌入函数调用是否有意义。如果答案是肯定的,在什么情况下有什么限制?
实际上,我问这个问题是因为我看了一段代码,有人从内联函数中调用 "socket()"、"sendto()" 和 "memset()" 等函数;在我看来,这超越了内联函数的目的。
注意:在我的代码中没有使用任何条件调用函数,内联函数只是将参数传递给被调用函数。
I wonder if it make sense to embed functions calls inside an inline function.
当然可以。内联对函数的调用仍然是一种优化,消除了该函数调用的成本并允许在调用函数的上下文中进行进一步优化,无论它是否依次调用其他函数。
in which context and what are the restrictions?
我不知道你说的 "context" 是什么意思;但是在内联函数中可以做什么没有限制。声明函数 inline
的唯一语义影响是允许多个相同的定义,并且需要在使用该函数的任何翻译单元中定义。在所有其他方面,它与任何其他函数定义相同。
编译器会选择何时内联。并且您应该避免以暴露您的实现为代价尝试过早优化。
编译器可能能够优化您正在调用的函数的转发。即使您不使用 inline 关键字,它也可能会通过优化标志执行此操作。
使用 inline
关键字的时间是当您想要制作一个仅用于多个项目的头文件而不必使用 link 库时。实际上,这根本不是 "inline" 的意思,而是 "one definition only" 甚至跨编译单元调用该函数的意思。
无论如何你应该看看这个 wiki 问题/答案:
Benefits of inline functions in C++?
首先,在 C++ 中,"inline" 函数(在头文件中声明或标记为这样的函数)只是对编译器的建议。编译器本身将决定是否真正使其内联。
内联函数的三个原因:
- 将另一轮变量压入堆栈的代价很高,分支到程序中的新点也是如此。
- 有时我们可以对函数的中间部分进行局部优化(尽管我不会指望它!)
- 将函数的定义放在头文件中(解决方法)。
举个例子
void NonInlinable(int x);
inline void Inline() { NonInlinable(10);}
内联很有意义。我删除了 1 个函数调用,所以如果 NonInlinable 非常快,那么这可能是一个巨大的加速。所以不管我是否调用函数,我仍然想内联调用。
再举一个例子:
inline int Inline(int y) {return y/10;}
//main
...
int x = 5;
int y = Inline(5);
int z = x % 10;
模运算和除运算通常由同一条指令计算。一个非常好的编译器,可以在 1 条汇编指令中计算 y 和 z! 魔法
所以在我看来,一个更好的问题是我什么时候应该不使用内联函数:
- 当我想将定义与声明分开时(对于可读性来说是非常好的做法,过早的优化是万恶之源)。
- 当我想隐藏我的implementation/use封装好
很有道理。
考虑一个由两个可能的执行分支组成的函数 — 一条在特定条件成立时(大部分时间)被激活的快速路径和一条慢速路径。
内联整个内容会增加代码的大小,但收效甚微。缓慢的路径复杂性可能会阻止编译器内联函数。
如果您将慢速路径变成一个单独的函数,就会出现一个有趣的机会。
它可以内联条件和快速路径,而慢速路径仍然是函数调用。内联快速路径可以避免大部分时间的函数调用开销。慢速路径已经很慢,因此调用开销可以忽略不计。
我看不出内联代码不能包含函数调用的先验原因。
抛开参数,内联插入代码行,减少调用开销并允许 local/ad-hoc 优化。
例如,当用 MyInline(false)
调用时,inline void MyInline(bool Perform) { if (Perform) memset(); }
很可能被跳过。
内联还可以允许内联内部函数调用,从而产生更多(微)优化机会。
评论作为答案发布,应要求:
如果编写代码的人认为 inline
对性能有任何有意义的影响,他显然不是 'doing the right thing'。
性能来自正确的算法选择和避免缓存未命中。
令人头疼的是幼稚的过早优化技术,这些技术可能在 1991 年就奏效了
据我所知,内联函数是一种增强性能的优化,因此它应该 运行 与宏一样快。内联函数的代码尽量短
我想知道在内联函数中嵌入函数调用是否有意义。如果答案是肯定的,在什么情况下有什么限制?
实际上,我问这个问题是因为我看了一段代码,有人从内联函数中调用 "socket()"、"sendto()" 和 "memset()" 等函数;在我看来,这超越了内联函数的目的。
注意:在我的代码中没有使用任何条件调用函数,内联函数只是将参数传递给被调用函数。
I wonder if it make sense to embed functions calls inside an inline function.
当然可以。内联对函数的调用仍然是一种优化,消除了该函数调用的成本并允许在调用函数的上下文中进行进一步优化,无论它是否依次调用其他函数。
in which context and what are the restrictions?
我不知道你说的 "context" 是什么意思;但是在内联函数中可以做什么没有限制。声明函数 inline
的唯一语义影响是允许多个相同的定义,并且需要在使用该函数的任何翻译单元中定义。在所有其他方面,它与任何其他函数定义相同。
编译器会选择何时内联。并且您应该避免以暴露您的实现为代价尝试过早优化。
编译器可能能够优化您正在调用的函数的转发。即使您不使用 inline 关键字,它也可能会通过优化标志执行此操作。
使用 inline
关键字的时间是当您想要制作一个仅用于多个项目的头文件而不必使用 link 库时。实际上,这根本不是 "inline" 的意思,而是 "one definition only" 甚至跨编译单元调用该函数的意思。
无论如何你应该看看这个 wiki 问题/答案:
Benefits of inline functions in C++?
首先,在 C++ 中,"inline" 函数(在头文件中声明或标记为这样的函数)只是对编译器的建议。编译器本身将决定是否真正使其内联。
内联函数的三个原因:
- 将另一轮变量压入堆栈的代价很高,分支到程序中的新点也是如此。
- 有时我们可以对函数的中间部分进行局部优化(尽管我不会指望它!)
- 将函数的定义放在头文件中(解决方法)。
举个例子
void NonInlinable(int x);
inline void Inline() { NonInlinable(10);}
内联很有意义。我删除了 1 个函数调用,所以如果 NonInlinable 非常快,那么这可能是一个巨大的加速。所以不管我是否调用函数,我仍然想内联调用。
再举一个例子:
inline int Inline(int y) {return y/10;}
//main
...
int x = 5;
int y = Inline(5);
int z = x % 10;
模运算和除运算通常由同一条指令计算。一个非常好的编译器,可以在 1 条汇编指令中计算 y 和 z! 魔法
所以在我看来,一个更好的问题是我什么时候应该不使用内联函数:
- 当我想将定义与声明分开时(对于可读性来说是非常好的做法,过早的优化是万恶之源)。
- 当我想隐藏我的implementation/use封装好
很有道理。
考虑一个由两个可能的执行分支组成的函数 — 一条在特定条件成立时(大部分时间)被激活的快速路径和一条慢速路径。
内联整个内容会增加代码的大小,但收效甚微。缓慢的路径复杂性可能会阻止编译器内联函数。
如果您将慢速路径变成一个单独的函数,就会出现一个有趣的机会。
它可以内联条件和快速路径,而慢速路径仍然是函数调用。内联快速路径可以避免大部分时间的函数调用开销。慢速路径已经很慢,因此调用开销可以忽略不计。
我看不出内联代码不能包含函数调用的先验原因。
抛开参数,内联插入代码行,减少调用开销并允许 local/ad-hoc 优化。
例如,当用 MyInline(false)
调用时,inline void MyInline(bool Perform) { if (Perform) memset(); }
很可能被跳过。
内联还可以允许内联内部函数调用,从而产生更多(微)优化机会。
评论作为答案发布,应要求:
如果编写代码的人认为 inline
对性能有任何有意义的影响,他显然不是 'doing the right thing'。
性能来自正确的算法选择和避免缓存未命中。
令人头疼的是幼稚的过早优化技术,这些技术可能在 1991 年就奏效了