使用大量C代码块会导致性能下降吗?

时间:2012-07-10 12:11:44

标签: c macros block

我想按照以下几行定义一个宏:

#define MYCheckedCall(stmnt) do {         \
    status_t status = (stmnt);            \
    if (MYFail(status)) {                 \
        MYLog("Statement failed!");       \
    }                                     \
} while (0)

每隔几次通话就可以在整个应用程序中使用它。这与每个地方重复代码的性能特征有什么关系? (即只定义status_t一次,没有额外的{}范围)

需要注意几点:

  • 这会在堆栈中添加一个框架(用于存储status_t变量),因此我对perf有好奇心。
  • status_t是typedef int status_t或类似内容。
  • 这将用于整个lib的代码的一半。

我知道这有点过早优化,但只是想知道它,不管它看起来应该是一个微不足道的决定吗?


现在代码的示例(没有宏):

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菜鸟并且有更好的模式/方式来实现这种功能,我也很想知道它。

我在Mac OS X 10.7上使用clang / llvm-gcc。

3 个答案:

答案 0 :(得分:6)

假设status_t是一个整数类型,我希望零开销,因为status每次都会存储在寄存器中,或者最坏的存储在同一个堆栈槽中;编译器不会打扰调整堆栈,因为它只能保留函数入口所需的最大堆栈空间并重用相同的堆栈槽。

如果您感兴趣,请务必检查汇编程序输出以确认这是编译器的作用。

答案 1 :(得分:6)

过早优化不应该是一个担心。此外,代码大小通常也不是性能的可靠指标(认为重复一百万次的三行循环比一千条指令的程序花费大约一千倍的时间)。所以,请稍后考虑优化。

在您的情况下,我不相信存在差异,因为预处理器会使用您为宏创建的代码替换所有宏调用。所以,基本上你在谈论相同的代码(检查this definition)。

答案 2 :(得分:1)

我不担心这个特定结构的性能。如果以后的分析证明它是一个瓶颈,那么你可以优化它。而不是宏,我会使用一个函数。一旦你想扩展它,宏很快就会成为维护的噩梦。

void MYCheckedCall (status_t status, const char *fail_message)
{
    if (MYFail(status))
    {
        MYLog(fail_message);
    }
}

MYCheckedCall(call1(), "call1 failed!");
MYCheckedCall(call2(), "call2 failed!");

甚至可能将其重命名为MYStatusCheck,因为这是函数/宏实际执行的操作。