Unexpected behaviour with #define and std:min()

While participating in the May long challenge (more specifically the question CHEFCK ), I encountered some unexpected behaviour.

While trying to optimize my solution, I replaced the std:min() function with a preprocessor directive ( #define ), expecting that since std:min() is a function, replacing it with a #define might save function calls and decrease execution time (at least remain the same).

However,to my surprise,not only did the time not decrease,it increased !.Even more surprisingly, it increased by more than 2.41 seconds.

That’s it,just replacing :
std:min()
by
#define min(a,b) (((a)<(b))?(a):(b))

increased the execution time drastically.
Can anyone please explain this behaviour ?
Thanks

Solution with #define

Solution with std::min

P.S. : I tried the same thing afterwards with FRMQ,only to notice a similar increase in runtime.

Hello, first let us observe what #define mean : When you define some thing using #define, the compiler replaces the respective term with the corresponding value while compiling. That is for example you used :

#define Max 10
so while compiling the compiler replaces the term "Max" with 10.

So in your case, the compiler replaces max(a, b) with (((a)<(b))?(a):(b)). So here the comprision of a,b is done with out function calls. As function calls are costly, so your second case(using std::min(), where you are calling inbuilt min() function) is slower than your first case(directly comparing values of ‘a’ and ‘b’).Hope you understood!

Best,
Chaitanya.

It’s a classic trap you’d need to watch out for when using #define. Let’s take this excerpt from your solution:

return min(getmin(s,m,qs,qe,2b+1),getmin(m+1,e,qs,qe,2b+2));

With #define, the preprocessor replaces that line with the following:

return (((getmin(s,m,qs,qe,2b+1))<(getmin(m+1,e,qs,qe,2b+2)))?(getmin(s,m,qs,qe,2b+1)):(getmin(m+1,e,qs,qe,2b+2)));

Basically, the program winds up calling the same two functions twice. You can avoid it by storing the results in temporary variables, then passing those variables to the min macro. However, I think that you would not have seen much of an improvement. It’s likely that the compiler is smart enough to inline the std::min function, so there will not have been any function call overhead.

1 Like