Ternary clamp or if-else clamp

By , last updated October 4, 2019

I have wondered what is the real difference between ternary clamp or if-else clamp. So I did some testing.

Starting with the following methods, which are the quicker one?

// Ternary clamp
template
inline T clamp_ternary(const T &x, const T &a, const T &b)
{
	return x < a ? a : (x > b ? b : x);
}

// If-else clamp
template
inline T clamp_ifelse(const T &x, const T &a, const T &b)
{
	if ( x < a ) 
	{
 		return a;
 	}
 	else if ( x > b )
	{
		return b;
	}

	return x;
}

From those I constructed two identical test cases where the only difference is the method used. The method is used to clamp an array of 10 million random integers.

duration test_ifelse(vector<int> &values)
{
	values.clear();

	srand(0);

	const int NUMBERS = 10000000;
	values.resize( NUMBERS );

	for (size_t i=0; i<NUMBERS; ++i)
	{
		values[ i ] = rand();
	}

	time_point begin( start() );

	for (size_t i=0; i<NUMBERS; ++i)
	{
		int &value = values[i];

		value = clamp_ifelse(value, 100, 1000);
	}

	return stop(begin);
}

The ternary test is identical, except it calls clamp_ternary instead.

I hoped the results where similar, and I somewhat got what I hoped for. But not quite. The tests were run in debug, release and release candidate modes, where the last one is like release but with even more optimizations turned on. Turns out there is no real difference between the two methods. They are in general equally quick.

The raw results with three runs each.

Debug build:

Debug>performancetests.exe
ifelse_clamp duration: 0.943094
ternary_clamp duration: 0.964096

Debug>performancetests.exe
ifelse_clamp duration: 0.943094
ternary_clamp duration: 0.964096

Debug>performancetests.exe
ifelse_clamp duration: 0.944094
ternary_clamp duration: 0.962096



Release build:

Release>performancetests.exe
ifelse_clamp duration: 0.0110011
ternary_clamp duration: 0.0120012

Release>performancetests.exe
ifelse_clamp duration: 0.0110011
ternary_clamp duration: 0.0130013

Release>performancetests.exe
ifelse_clamp duration: 0.0110011
ternary_clamp duration: 0.0110011



ReleaseCand results:

ReleaseCand>performancetests.exe
ifelse_clamp duration: 0.0170017
ternary_clamp duration: 0.0170017

ReleaseCand>performancetests.exe
ifelse_clamp duration: 0.0160016
ternary_clamp duration: 0.0170017

ReleaseCand>performancetests.exe
ifelse_clamp duration: 0.0160016
ternary_clamp duration: 0.0160016