chakrit
chakrit

Reputation: 61518

Does using lots of C code blocks incur performance hit?

I'd like to define a macro along the lines of the following:

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

And use it throughout the applications every few calls. What is the performance characteristics of this versus just repeating the code every where? (i.e. only define status_t once and no extra {} scope)

Couple of points to note:

I know this is a bit of premature optimization but just wanna know about it regardless since it seems like it should've been a trivial decision?


Example of what the code looks like right now (without the macro):

status_t status = 0;
status = call1();
if (MYFail(status)) MYLog("call1 failed!");

status = call2();
if (MYFail(status)) MYLog("call2 failed!");

Example of what I'd like it be with the macro:

MYCheckedCall( call1() );
MYCheckedCall( call2() );

If I'm just being C noob and there is a better pattern/way to implement this kind of functionality, I'd would love to know about it as well.

I'm using clang/llvm-gcc on Mac OS X 10.7.

Upvotes: 1

Views: 244

Answers (3)

Secure
Secure

Reputation: 4378

I would not worry about performance at all for this specific construct. If profiling later proves that it is a bottleneck, then you can optimize it. And instead of the macro, I would use a function. A macro can quickly become a maintenance nightmare, once you want to extend it.

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

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

Maybe even rename it to MYStatusCheck, because this is what the function/macro actually does.

Upvotes: 1

rlinden
rlinden

Reputation: 2041

Premature optimization should not be a worry. Besides, code size usually is not a reliable indicator of performance either (think that a three line loop that repeats a million times will take about a thousand of time longer than a program with a thousand instructions). So, think about optimization later.

In your case, I don't believe there is a difference, because the pre-processor with replace all your macro calls with the code you created for the macro. So, essentially you are talking about the same code (check this definition).

Upvotes: 6

ecatmur
ecatmur

Reputation: 157344

Assuming status_t is an integral type, I'd expect there to be zero overhead as status would be stored in a register or at worst in the same stack slot each time; the compiler won't bother adjusting the stack as it can just reserve the maximum stack space required on function entry and reuse the same stack slot.

As always if you're interested you should check the assembler output to confirm that this is what the compiler does.

Upvotes: 6

Related Questions