Jump to content
  • Advertisement
Sign in to follow this  
tmunq

Deriving classes from fundamental types [C++]

This topic is 4893 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is this even possible? // This works float a = 2.0f, b = 3.0f; a = a + b * 2.5f; // This also works typedef float value; value a = 2.0f, b = 3.0f; a = a + b * 2.5f; Now, how do I add methods to that 'value' data type? This is one work-around you could use but it is really slow: class value { float _value: public: value(){_value = 0.0f;} value(float val){_value = val;} operator float() {return _value;} operator = (float val) {_value = val;} template <typename T> value operator + (T val) {return value(_value + (float)val);} template <typename T> value operator * (T val) {return value(_value * (float)val);} // etc... }; // Now I can write: value a = 2.0f, b = 3.0f; a = a + b * 2.5f; The thing is, however, that this is really slow. I ran some test and it seems that it is almost 10 times slower! I also have to define all the different operators and shit.. How do I do someting like this: class value : public float { public: void dosomething(); }; // this part should be just as fast as with normal floats.. value a = 2.0f, b = 3.0f; a = a + b * 2.5f; a.dosomething();

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by tmunq
The thing is, however, that this is really slow. I ran some test and it seems that it is almost 10 times slower! I also have to define all the different operators and shit..


I don't see how this could possibly be slow; the compiler should inline it and produce the same code as for normal plain float... Did you run your tests with all optimizations enabled? Could you maybe post your benchmarking code?

Otherwise - you can't inherit primitive types in C++, so I suppose this is the only way how to do it. Or you could also use a good ol' free function, i.e. void dosomething(const float f) { /* whatever */ }

Oxyd

Share this post


Link to post
Share on other sites
I think you're over-thinking this. Just write some functions that take a float as a parameter and you'll be fine (plus save yourself tons of time).

Is having the extra elegance of it all being in a class really worth the time you'll have to spend typing it all up? I don't think so.

Share this post


Link to post
Share on other sites
Here are the only two files you need: (console app)

/////////////
// tmath.h //
/////////////

namespace tmath
{
class value
{
private:
float _value;
public:
value() {_value = 0.0f;}
value(float val) {_value = val;}

operator float() {return _value;}

void operator = (float val) {_value = val;}

template <typename T>
value operator + (T val) {return value(_value + (float)val);}
template <typename T>
value operator - (T val) {return value(_value - (float)val);}
template <typename T>
value operator * (T val) {return value(_value * (float)val);}
template <typename T>
value operator / (T val) {return value(_value / (float)val);}

template <typename T>
void operator += (T val) {_value += (float)val;}
template <typename T>
void operator -= (T val) {_value -= (float)val;}
template <typename T>
void operator *= (T val) {_value *= (float)val;}
template <typename T>
void operator /= (T val) {_value /= (float)val;}
};
}

//////////////
// main.cpp //
//////////////

#include <windows.h>

#include <iostream>
using namespace std;

#include "tmath.h"
using namespace tmath;

template <typename T>
void test()
{
T a=5.0f, b=2.0f;

unsigned long int i1,i2;

for(i1 = 0 ; i1 < 8000 ; i1++)
{
for(i2 = 0 ; i2 < 8000 ; i2++)
{
a = 5.0f;
a = a + b;
}
}
}

int main()
{
DWORD time1,time2;

time1 = timeGetTime();
test<float>();
time2 = timeGetTime();
cout<<"Test <float>. Time elapsed in ms: "<<time2-time1<<'\n';

time1 = timeGetTime();
test<value>();
time2 = timeGetTime();
cout<<"Test <value>. Time elapsed in ms: "<<time2-time1<<'\n';

return 0;
}


I'm using:
Microsoft Visual Studio .NET 2003
Release Configuration
Optimization: Maximize speed (/O2)

I just got:
178 ms
1368 ms
WTF!!!

Share this post


Link to post
Share on other sites
make sure you test the speed in Release mode. the code would obviously be slower in Debug since it does not optimize at all.

Share this post


Link to post
Share on other sites
That's weird... I made a quick test of my own:


#include <iostream>
#include <ostream>
#include <ctime>

class Value {
public:
Value() { value_ = 0.0f; }
Value(const float value) { value_ = value; }
const Value &operator=(const float rhs) {
value_ = rhs;
return *this;
}

operator float() { return value_; }

template <typename T>
Value operator+(T &rhs) { return Value(value_ + (float)rhs); }
template <typename T>
void operator+=(T rhs) { value_+= (float)rhs; }

private:
float value_;
};

template <typename T>
T test() {
T total = 0.0f;
unsigned long i1, i2;

for (i1 = 0; i1 < 8000; i1++) {
for (i2 = 0; i2 < 8000; i2++) {
T a, b;
a = (T)(rand() % 1000);
b = (T)(rand() % 100);
total+= a + b;
}
}

return total;
}

int main() {
clock_t time1, time2;

srand(time(0));

time1 = clock();
std::cout << test<float>() << '\n';
time2 = clock();
std::cout << "With floats: " << ((double)(time2 - time1)) / CLOCKS_PER_SEC << '\n';

time1 = clock();
std::cout << (float)test<Value>() << '\n';
time2 = clock();
std::cout << "With Value: " << ((double)(time2 - time1)) / CLOCKS_PER_SEC << '\n';
}



Which I then compiled with:
$ make
g++ -c -O3 -W -Wall test.cpp -o test.o
g++ test.o -o test

And got this result:
$ ./test 
1.90663e+10
With floats: 5.7
1.90685e+10
With Value: 5.34

Compiled with g++ 3.4.4

Oxyd

EDIT: Changed my code, since the previous one's algorithm was not connected to the output and the compiler could have optimized the whole thing out [rolleyes]

[Edited by - Oxyd on July 24, 2005 1:07:46 PM]

Share this post


Link to post
Share on other sites
I just compiled my code using Dev-C++ that uses mingw and I got 52 milliseconds for both. Now I'm seriously pissed!

Edit:

It looks like I have an edition of VC++ that does not support optimization!!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by tmunq
I just compiled my code using Dev-C++ that uses mingw and I got 52 milliseconds for both. Now I'm seriously pissed!

Edit:

It looks like I have an edition of VC++ that does not support optimization!!


They all support it. Make sure you change the build configureation to Release. Then, under Project > Settings, expand C++ > Optimization and you should see lots of options.

Share this post


Link to post
Share on other sites
Dude, I have release mode. The optimization stuff is pretty much greyed out. So I try to add /O2 manually to the command line.

Compiling...
cl : Command line warning D4029 : optimization is not available in the standard edition compiler

Sweet!

Edit: Thx Oxyd, you have been helpful.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!