Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing away function calls

Is it a conceivable that a C++ compiler would optimize out a function call to a class member function that only sets class variables? Example:

class A
{
    private:
        int foo;
    public:
        void bar(int foo_in)
        {
             foo = foo_in;
        }
}

So if I did this

A test;
A.bar(5);

could a compiler optimize this to directly access the member and set it like so?

like image 511
chbaker0 Avatar asked Dec 04 '13 17:12

chbaker0


2 Answers

Yes, it is called inlining.

Moreover c++ is designed specifically to support, or make it easier for the compiler to perform, such optimizations in quite complex inheritance cases and templates.

Some would say this is quite distinctive feat of c++ as a high level language compared to others. Its "high level" features (mostly I mean generic programming - templates) were designed with such optimizations in mind. It is also one of the reasons that makes it considered as efficient in terms of performance.

This is also why would I expect a decent job at working out inlines with any reputable compiler.

From what I've read, this is also the reason why it is hard to get all the fancy stuff of other high-level languages such as Reflection mechanism, or other known from e.g. Java or python. It is because c++ is designed to easily allow to inline pretty much everything possible, so it's hard to introspect optimized code.

Edit:

Because you said you are writing an OpenGL stuff where performance of setters and getter and such optimizations do matter I decided to elaborate a bit and show a bit more interesting example where you can rely on inline mechanism.

You can write some interfaces avoiding the virtual mechanism but using templates. E.g:

//This is a stripped down interface for matrices for physical objects
//that have Hamiltonian and you can apply external field and temperature to it
template< class Object >
class Iface {
protected:  
    Object& t;

public:
  Iface(Object& obj) : t(obj) {};

  Vector get_eigen_vals() {return t.get_eigen_vals(); };
  Matrix get_eigen_vectors() {return t.get_eigen_vectors(); };

  void set_H(VectorD vect) { t.set_H(vect); };
  void set_temp(double temp)   {t.set_temp(temp);};
};

If you declare interface like this, you can wrap an object with this interface object, and pass instance of this interface class to your functions/algorithms, and still have everything inlined because it works on the reference of Object. Good compiler optimizes whole Iface out.

like image 57
luk32 Avatar answered Oct 12 '22 21:10

luk32


To answer the question a little bit more generally than just inlining:

There is something in the standard known as the as-if rule. It says that the compiler is allowed to make any change to your program as long as it doesn't affect the observable behaviour. There are even exemptions that allow them to change things that technically do change the observable behaviour.

It can elide function calls and even complete classes. It can do basically whatever it wants as long as it doesn't break anything.

like image 25
Tim Seguine Avatar answered Oct 12 '22 19:10

Tim Seguine