Avatar of Unimatrix_001
Unimatrix_001Flag for United Kingdom of Great Britain and Northern Ireland

asked on 

Function pointers vs if statements - speed.

Hi,

I know that if called many times then a function pointer would be faster than an if and then calling the appropriate function. Although from wiki:

<b>
Extensively using function pointers to call functions may produce a slow-down for the code on modern processors, because branch prediction may not be able to figure out where to branch to (it depends on the value of the function pointer at run time).
</b>

So, with this in mind, is using function pointers extensively actually beneficial vs using if statements?

Thanks,
Uni
C++

Avatar of undefined
Last Comment
evilrix
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> So, with this in mind, is using function pointers extensively actually beneficial vs using if statements?
Um, it really depends on what you are trying to do. In C++ it is preferable to use functors rather than function pointers.
http://www.newty.de/fpt/functor.html#chapter4
#include <iostream>
 
struct functor
{
	void operator()() const
	{
		std::cout << "hello world" << std::endl;
	}
};
 
template <typename funcT>
void foo(funcT const & func)
{
	func();
}
 
int main()
{
	foo(functor());
}

Open in new window

Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Hm, I haven't heard of functors before... Why does it depend on what I'm trying to do?
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of RishadanPort
RishadanPort

One thing I don't understand is why you need your performence based on using function pointers / if statements? Honestly sure one may be slower then the other, but it is really not that significant versus changing the programs logic to be optimal
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> What I mean is, there is no right or wrong answer to your question
Or, to put it another way, if you need to use function pointers then use them and if you don't need to use them then don't. Use the right tool for the right job. I wouldn't use a chain saw to cut my hair just because it is quicker :)
Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Thanks. :)
Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Rishadan: The reason I ask is because this will be called hundreds of times per second, so clearly if there is a better way, I'll take it. :)
Avatar of RishadanPort
RishadanPort

Hmm. Why are you calling this hundreds of times per second. Maybe you could improve on your logic such that you don't have to call it 100 times per second.
Avatar of RishadanPort
RishadanPort

well to be honest 100 times per second, is slow is computer terms
Avatar of RishadanPort
RishadanPort

Or rather 100 times per second is not many at all...
Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Sorry, that should have been hundreds of thousands - probably going into the double digit millions.

>>Maybe you could improve on your logic such that you don't have to call it 100 times per second.
No, unfortunately not.

>>well to be honest 100 times per second, is slow is computer terms
Agreed. :)
Avatar of Infinity08
Infinity08
Flag of Belgium image

evilrix's answer is excellent of course, and is the one to go with. But I just wanted to clarify the wiki quote (in case it needs clarification). If the function call will be done in an inner loop (ie. will be executed a lot of times), then it's likely to be faster to make use of if statements for choosing which function to call. If the function call is not done regularly, then the application design or code clarity or ... might push you towards using function pointers.

But I'd hold on to the "premature optimization is the root of all evil" quote ;)
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

I wouldn't do either. I'd use polymorphism.
Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

>>I wouldn't do either. I'd use polymorphism.
How exactly do you mean?

Thanks,
Uni
Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Btw, I don't mean how do you use polymorphism, but how would it help in this type of case?
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> but how would it help in this type of case?
Rather than using function pointer I'd use polymorphic functors.
#include <iostream>
 
struct functor_base
{
	virtual void operator()() const = 0;
};
 
struct functor1 : functor_base
{
	virtual void operator()() const
	{
		std::cout << "functor1" << std::endl;
	}
};
 
struct functor2 : functor_base
{
	virtual void operator()() const
	{
		std::cout << "functor2" << std::endl;
	}
};
 
void foo(functor_base & functor)
{
	// No if's or function pointer.
	functor();
}
 
 
int main()
{
	foo(functor1());
	foo(functor2());
}

Open in new window

Avatar of Infinity08
Infinity08
Flag of Belgium image

>> Rather than using function pointer I'd use polymorphic functors.

The "issue" with compiler optimizations (branch prediction etc.) is similar to when using function pointers though.
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> The "issue" with compiler optimizations (branch prediction etc.) is similar to when using function pointers though.
I wasn't suggesting I'd do it that way for optimization (see my comment above about premature optimization) I was suggesting I'd do it that way as I believe it'd make the code cleaner.
Avatar of Infinity08
Infinity08
Flag of Belgium image

I know ;) Just making sure there are no misunderstandings for Unimatrix_001. Might also be because I'm very tired but don't want to sleep, so I'm trying to keep myself busy by just posting whatever comes up in my mind. Maybe I should just go to bed and get it over with ... heh ... think I'll do that.
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> Just making sure there are no misunderstandings for Unimatrix_001
No worries :)
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> Rather than using function pointer I'd use polymorphic functors.
I meant to point out last night (but like I8 I really should have gone to bed earlier)...

If performance of the dynamic polymorphic approach proves to be unacceptable you can always change it, quite simply, to use static polymorphism. This will avoid the use of the virtual functions (which are usually implemented as function pointers held in a v-table) but at the cost of a bigger exe and slower compile times (since templates will need to be instantiated for each functor). I'd go with the dynamic approach first and profile it and only change it if you feel it is necessary.
#include <iostream>
 
struct functor1
{
	virtual void operator()() const
	{
		std::cout << "functor1" << std::endl;
	}
};
 
struct functor2
{
	virtual void operator()() const
	{
		std::cout << "functor2" << std::endl;
	}
};
 
template <typename funcT>
void foo(funcT & functor)
{
	// No if's or function pointer.
	functor();
}
 
 
int main()
{
	foo(functor1());
	foo(functor2());
}

Open in new window

Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

^^^ oops, I forgot to remove the virtual keyword (I've just woken up -- tsk!) :)
#include <iostream>
 
struct functor1
{
	void operator()() const
	{
		std::cout << "functor1" << std::endl;
	}
};
 
struct functor2
{
	void operator()() const
	{
		std::cout << "functor2" << std::endl;
	}
};
 
template <typename funcT>
void foo(funcT & functor)
{
	// No if's or function pointer.
	functor();
}
 
 
int main()
{
	foo(functor1());
	foo(functor2());
}

Open in new window

Avatar of Unimatrix_001
Unimatrix_001
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Hehehe - cheers for the extra info lads. Much appreciated...

>>(I've just woken up -- tsk!) :)
Ah, it's Saturday though. ;)

Uni
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

No worries Uri... good luck ;)
C++
C++

C++ is an intermediate-level general-purpose programming language, not to be confused with C or C#. It was developed as a set of extensions to the C programming language to improve type-safety and add support for automatic resource management, object-orientation, generic programming, and exception handling, among other features.

58K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo