嵌入式C基础——inline的作用
内联函数技巧声明
·
本期主题:
讲解inline的作用,并用实例来掩饰:
- 什么是inline,为什么要用inline
- 简单例子
- 实践中inline的使用方式
往期链接:
1. inline的作用
我们经常能看到形如这样的代码:
static inline void xxxx(xxx)
{
....
}
inline的作用是这样的:
在C语言中,inline 用于告诉编译器尝试将函数的代码插入到调用它的地方,而不是生成一个函数调用。
那么使用inline与传统的函数调用相比,有哪些好处呢?
总结一下使用inline的好处如下:
性能优化:
内联函数可以减少函数调用的开销,因为它会直接将函数的代码插入到调用处,避免了函数调用时的参数传递、栈帧保存和恢复等操作。这对于频繁调用的小型函数特别有效,可以提高程序的执行效率。减少函数调用开销:
函数调用会导致栈帧的建立和销毁,以及跳转到函数的代码位置,这些都会带来一定的性能开销。通过内联函数,可以避免这些开销,从而提高程序的性能。编译器优化:
内联函数使得编译器更容易进行优化。在内联函数中,编译器可以更好地进行函数内联、常量折叠、循环展开等优化操作,从而生成更高效的代码。避免宏的缺点:
内联函数可以避免使用宏带来的一些问题,比如宏的参数可能会被多次计算、宏的作用域可能会引起命名冲突等。内联函数在语法上更加清晰、安全,并且可以进行类型检查和错误检查。总的来说,内联函数是一种优化手段,适合于频繁调用、函数体较小的情况下,可以提高程序的性能和可读性。但在使用内联函数时,也需要注意不要滥用,否则可能会导致代码膨胀、可维护性下降等问题。
2. 实例测试
看一个具体例子,用inline和不用inline的耗时对比,运行同一段简单的程序
#include <stdio.h>
#include <time.h>
// #include "add_inline.h"
#define LOOP_TIMES 10000000
// 非内联加法函数
int add(int a, int b) {
return a + b;
}
// 内联加法函数
static inline int add_inline(int a, int b) {
return a + b;
}
long long get_current_time_us() {
struct timespec current_time;
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
return current_time.tv_sec * 1000000LL + current_time.tv_nsec / 1000LL;
}
int main(void)
{
int a, b;
int time_cost = 0;
long long start_time = get_current_time_us();
for (int i = 0; i < LOOP_TIMES; i++) {
add(a, b);
}
long long end_time = get_current_time_us();
long long execution_time_us = end_time - start_time;
printf("No inline Execution time (us): %lld\n", execution_time_us);
start_time = get_current_time_us();
for (int i = 0; i < LOOP_TIMES; i++) {
add_inline(a, b);
}
end_time = get_current_time_us();
execution_time_us = end_time - start_time;
printf("Inline Execution time (us): %lld\n", execution_time_us);
return 0;
}
运行结果:
$ ./a.out
No inline Execution time (us): 23235
Inline Execution time (us): 21733
从结果可以看出,inline的方式确实时间会更短一些。
3. inline的使用技巧
总结一下inline的使用技巧:
inline修饰的函数一般适合放在头文件中:
这是因为内联函数的本质是在调用点直接插入函数体,因此编译器需要在每个调用点都能够看到函数的定义,以便进行内联。小型函数:
内联函数适合用于函数体较小的情况。一般来说,函数的代码应该足够简短,以便于被内联到调用处,避免代码膨胀。频繁调用:
内联函数适合用于被频繁调用的函数。因为内联函数可以减少函数调用的开销,对于频繁调用的函数可以提高程序的性能。避免函数调用开销:
内联函数适合用于需要避免函数调用开销的情况。比如,在性能敏感的代码中,可以将一些关键的函数标记为内联,从而减少函数调用带来的性能损失。简单数据类型:
内联函数适合用于处理简单数据类型的情况。对于复杂的数据类型或者涉及到大量计算的函数,内联可能并不适合,因为内联会导致代码膨胀。短小明了的代码:
内联函数适合用于代码逻辑简单明了的情况。内联函数的定义应该清晰易懂,不涉及复杂的逻辑或控制流程。避免滥用:
内联函数应该谨慎使用,避免滥用。过度使用内联函数可能会导致代码膨胀、可读性下降等问题,应该根据实际情况进行权衡。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献4条内容
所有评论(0)