Question

Let's say I have a class that's something like this:

class View
{
public:
    View(DataContainer &c)
        : _c(c)
    {
    }

    inline Elem getElemForCoords(double x, double y)
    {
        int idx = /* some computation here... */;
        return _c.data[idx];
    }

private:
    DataContainer& _c;
};

If I have a function using this class, is the compiler allowed to optimize it away entirely and just inline the data access?

Is the same still true if View::_c happens to be a std::shared_ptr?

Was it helpful?

Solution

If I have a function using this class, is the compiler allowed to optimize it away entirely and just inline the data access?

Is the same still true if View::_c happens to be a std::shared_ptr?

Absolutely, yes, and yes; as long as it doesn't violate the as-if rule (as already pointed out by Pentadecagon). Whether this optimization really happens is a much more interesting question; it is allowed by the standard. For this code:

#include <memory>
#include <vector>

template <class DataContainer>
class View {
public:
    View(DataContainer& c) : c(c) { }

    int getElemForCoords(double x, double y) {
        int idx = x*y; // some dumb computation
        return c->at(idx);
    }
private:
    DataContainer& c;
};

template <class DataContainer>
View<DataContainer> make_view(DataContainer& c) {
  return View<DataContainer>(c);
}

int main(int argc, char* argv[]) {

  auto ptr2vec = std::make_shared<std::vector<int>>(2);

  auto view = make_view(ptr2vec);

  return view.getElemForCoords(1, argc);
}

I have verified, by inspecting the assembly code (g++ -std=c++11 -O3 -S -fwhole-program optaway.cpp), that the View class is like it is not there, it adds zero overhead.


Some unsolicited advice.

  • Inspect the assembly code of your programs; you will learn a lot and start worrying about the right things. shared_ptr is a heavy-weight object (compared to, for example, unique_ptr), partly because of all that multi-threading machinery under the hood. If you look at the assembly code, you will worry much more about the overhead of the shared pointer and less about element access. ;)

  • The inline in your code is just noise, that function is implicitly inline anyway. Please don't trash your code with the inline keyword; the optimizer is free to treat it as whitespace anyway. Use link time optimization instead (-flto with gcc). GCC and Clang are surprisingly smart compilers and generate good code.

  • Profile your code instead of guessing and doing premature optimization. Perf is a great tool.

  • Want speed? Measure. (by Howard Hinnant)

OTHER TIPS

In general, compilers don't optimize away classes. Usually, they optimize functions.

The compiler may decide to take the content of simple inlined functions and paste the content where the function is invoked, rather than making the inlined function a hard-coded function (i.e. it would have an address). This optimization depends on the compiler's optimization level.

The compiler and linker may decide to drop functions that are not used, whether they be class methods or free standing.

Think of the class as a stencil for describing an object. The stencil isn't any good without an instance. An exception is a public static function within the class (static methods don't require object instances). The class is usually kept in the compiler's dictionary.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top