If you have some property you would like to make available for some the objects of a hierarchy, there are two approaches:
- Define a pure virtual function in the base class and override it in the subclasses where it computes (or returns) the value.
- Add a member variable to the base class and compute the value in the constructor of the subclasses. Add a member function in the base class to fetch that value.
Virtual Functions | 1.05207 seconds | 100% |
---|---|---|
Member Variable | 0.136009 seconds | 13% |
Update: Adding -O4 improved the results significantly.
C++ code
Compiled usingg++ -O4 -std=c++0x vfunc-attr.cc -o vfunc-attr
#include <cstdlib> #include <sys/time.h> #include <sys/resource.h> #include <vector> #include <functional> #include <numeric> #include <iostream> #include <memory> #include <algorithm> class VBase { public: virtual size_t size() const = 0; }; class VInt : public VBase { public: template <class T> VInt(T value) : m_value(value) {} virtual size_t size() const { return sizeof(m_value); } private: int m_value; }; class VFloat : public VBase { public: template <class T> VFloat(T value) : m_value(value) {} virtual size_t size() const { return sizeof(m_value); } private: float m_value; }; class MBase { public: MBase(size_t size) : m_size(size) { } size_t size() const { return m_size; } private: size_t m_size; }; class MInt : public MBase { public: MInt(int value) : MBase(sizeof(m_value)), m_value(value) { } private: int m_value; }; class MFloat : public MBase { public: MFloat(int value) : MBase(sizeof(m_value)), m_value(value) { } private: float m_value; }; double operator-(rusage const& a, rusage const& b) { double result = (a.ru_utime.tv_usec - b.ru_utime.tv_usec) / 1.0e6; result += (a.ru_utime.tv_sec - b.ru_utime.tv_sec); return result; } template <class Func> double measure(Func func) { rusage before, after; getrusage(RUSAGE_SELF, &before); func(); getrusage(RUSAGE_SELF, &after); return (after - before); } int main() { { std::vector<VBase*> array; size_t sum = 0; for (int i = 0 ; i < 100000000 ; ++i) { if (i % 2 == 0) array.push_back(new VFloat(i)); else array.push_back(new VInt(i)); } double result = measure([&array, &sum](){ sum = std::accumulate(array.begin(), array.end(), 0, [](size_t x, VBase* ptr){ return x + ptr->size(); }); }); std::for_each(array.begin(), array.end(), std::default_delete<VBase>()); std::cout << "VBase - Sum is: " << sum << ", " << "Exec time is: " << result << std::endl; } { std::vector<MBase*> array; size_t sum = 0; for (int i = 0 ; i < 100000000 ; ++i) { if (i % 2 == 0) array.push_back(new MFloat(i)); else array.push_back(new MInt(i)); } double result = measure([&array, &sum](){ sum = std::accumulate(array.begin(), array.end(), 0, [](size_t x, MBase* ptr){ return x + ptr->size(); }); }); std::for_each(array.begin(), array.end(), std::default_delete<MBase>()); std::cout << "MBase - Sum is: " << sum << ", " << "Exec time is: " << result << std::endl; } }
No comments:
Post a Comment