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