使用大量C代码块会导致性能下降吗?
我想按照以下几行定义一个宏:使用大量C代码块会导致性能下降吗?,c,macros,block,C,Macros,Block,我想按照以下几行定义一个宏: #define MYCheckedCall(stmnt) do { \ status_t status = (stmnt); \ if (MYFail(status)) { \ MYLog("Statement failed!"); \ } \ } while (0) 并在
#define MYCheckedCall(stmnt) do { \
status_t status = (stmnt); \
if (MYFail(status)) { \
MYLog("Statement failed!"); \
} \
} while (0)
并在应用程序中每隔几次调用就使用它。与到处重复代码相比,它的性能特点是什么?(即只定义一次状态,没有额外的{}范围)
需要注意的几点:
- 这在堆栈中添加了一个框架(用于存储
变量),因此我对perf很好奇status\u t
- 状态是
或类似的东西typedef int status\u t
- 这将用于整个库中大约一半的代码
代码现在的样子示例(没有宏): 我希望宏是什么样的示例:
status_t status = 0;
status = call1();
if (MYFail(status)) MYLog("call1 failed!");
status = call2();
if (MYFail(status)) MYLog("call2 failed!");
MYCheckedCall( call1() );
MYCheckedCall( call2() );
如果我只是一个C noob,并且有更好的模式/方法来实现这种功能,我也很想了解它
我在Mac OS X 10.7上使用clang/llvm gcc。假设
status\u t
是一个整数类型,我希望开销为零,因为status
每次都会存储在寄存器中,最坏的情况是存储在同一堆栈插槽中;编译器不会费心调整堆栈,因为它可以保留函数项所需的最大堆栈空间,并重用相同的堆栈槽
像往常一样,如果您感兴趣,您应该检查汇编程序的输出,以确认编译器就是这样做的。假设
status\u t
是一个整数类型,我希望不会有任何开销,因为status
每次都会存储在寄存器中,最坏的情况是存储在同一堆栈插槽中;编译器不会费心调整堆栈,因为它可以保留函数项所需的最大堆栈空间,并重用相同的堆栈槽
像往常一样,如果您感兴趣,您应该检查汇编程序的输出,以确认这是编译器所做的。不应该担心过早优化。此外,代码大小通常也不是一个可靠的性能指标(想想一个重复一百万次的三行循环比一个有一千条指令的程序要花费一千倍的时间)。所以,以后再考虑优化
在您的情况下,我不认为有什么区别,因为带有的预处理器将用您为宏创建的代码替换所有宏调用。因此,本质上,您谈论的是相同的代码(检查)。过早优化不应该是一个问题。此外,代码大小通常也不是一个可靠的性能指标(想想一个重复一百万次的三行循环比一个有一千条指令的程序要花费一千倍的时间)。所以,以后再考虑优化
在您的情况下,我不认为有什么区别,因为带有的预处理器将用您为宏创建的代码替换所有宏调用。因此,基本上您所说的是相同的代码(检查)。对于这个特定的构造,我根本不担心性能。如果以后分析证明这是一个瓶颈,那么您可以对其进行优化。我用函数代替宏。一旦您想要扩展宏,它很快就会成为维护的噩梦
void MYCheckedCall (status_t status, const char *fail_message)
{
if (MYFail(status))
{
MYLog(fail_message);
}
}
MYCheckedCall(call1(), "call1 failed!");
MYCheckedCall(call2(), "call2 failed!");
甚至可以将其重命名为MYStatusCheck,因为函数/宏实际上就是这样做的。对于这个特定的构造,我根本不担心性能。如果以后分析证明这是一个瓶颈,那么您可以对其进行优化。我用函数代替宏。一旦您想要扩展宏,它很快就会成为维护的噩梦
void MYCheckedCall (status_t status, const char *fail_message)
{
if (MYFail(status))
{
MYLog(fail_message);
}
}
MYCheckedCall(call1(), "call1 failed!");
MYCheckedCall(call2(), "call2 failed!");
甚至可以将其重命名为MYStatusCheck,因为函数/宏实际上就是这样做的。我建议您将#define更改为funky
do{…}while(0)
样式,以允许在“if with dangling else”中使用它context@wildplasser好的,换了。谢谢我建议您将#define更改为funkydo{…}while(0)
样式,以允许在“if with dangling else”中使用它context@wildplasser好的,换了。谢谢对不起,这不能回答问题。我理解你关于过早优化的观点,以及如何在编译时替换宏等等。对不起,这并不能回答这个问题。我理解你关于过早优化的观点,以及如何在编译时替换宏等等。