I have two functions that do the same thing. Which one is faster?

Started by
18 comments, last by Khatharr 11 years, 3 months ago

I want to make my program run faster. I know pointers are quick but does using pointers in this following example increase or decrease speed?

If this is faster I plan on doing something similar with all my functions to increase the speed of my program.

Example 1. This is the first function returning type Entity.

This is the call.

*hero = hero->hero_turning(*hero,'d',mv);

This is the function

Entity Entity::hero_turning(Entity hero, char facing1, vector<Tile> mv) {
if (hero.is_swing_hoe == false) {
if(hero.facing != facing1) {
hero.facing = facing1;
hero.wait_time = 0;
}
else if (hero.can_pass(hero.facing,mv,hero)&& hero.wait_time > 3) {
hero.frame = 1;
hero.move_animation = true;
}
}
return hero;
}

Example 2. This one uses pointers and the function is void and doesn't return anything.

This is the call.

hero->hero_turning(hero,'u',mv);

This is the function

void Entity::hero_turning(Entity * hero, char facing1, vector<Tile> mv) {

if (hero->is_swing_hoe == false) {

if(hero->facing != facing1) {
hero->facing = facing1;
hero->wait_time = 0;
}

else if (hero->can_pass(hero->facing,mv,*hero)&& hero->wait_time > 3) {
hero->frame = 1;
hero->move_animation = true;
}
}
}

Advertisement

1st one is likely to be slower because Entity is copies. You couldn't copy vector<Tile> either, just pass reference/pointer.

Blindly making micro optimisations is not the solution. However, as you are modifying hero it doesn't make sense to pass by value then return the result a la function 1. This is less about "changing things because you want your program to run faster" and more about choosing the right tool for the right job in the first place. But back to my original point, if you are achieving sub-optimal framerates then there are almost certainly bigger fish to fry that will deliver real, tangible performance benefits. Profile first, identify bottlenecks THEN optimise.

There is a reason why second method (using pointers) is faster than the first one.

Processor doesn't have to calculate the memory offset of each member of the structure when using pointers which makes things run faster.

From personal experience, generally everyone knows why pointers are fast, but few people understand why.

But, like GeneralQuery mentioned above, optimisation is bound by many more factors and world peace is a myth.

However, for the question at hand, go ahead and use the second one.

I don't really get why you feel like you have to pass in Entity hero at all.
Smells like a design problem, my guess is that your "Entity" class tries to do way too much. (SRP violation)

That said, option one has a lot of potential problems, also problems that is not performance related, so its often not a good idea.
You certainly should not pass the vector<Tile> by value, but as a reference as mentioned.

Ignoring the design problems, in this case I would use a const Entity& for the parameter.
const references are your friend.

Edit: fixed bad formatting by broken post editor

Am I the only one being very confused by the fact that passing a the Entity hero as a parameter to its own member function seems extremely weird and pointless? This basically feels less like it should be "which is faster" and more "somebody please explain the point of member functions".

Your member function already has access to all the members of hero, so why would you pass it at all? Take the second one, remove every last "hero->" (or replace with "this->", depending on preference) and stop passing the object as a parameter to itself.

f@dzhttp://festini.device-zero.de
Please read a book about C++. You are calling a METHOD (as opposed to function). A method belongs to an object. Therefore, you can access a pointer to object you are calling your method from using keyword 'this'. So you can write

void Entity::turning(char facing1, vector<Tile> mv) {
    if (this->is_swing_hoe == false) {
                            if(this->facing != facing1) {
            this->facing = facing1;            this->wait_time = 0;
        }
        else if (this->can_pass(this->facing,mv,this)&& this->wait_time > 3) {
            this->frame = 1;            this->move_animation = true;
        }
    }
}
and 'this' will correspond to 'hero' if you call it like
hero->turning('d',mv);
Even better, you can remove all the 'this->' from above code. Your compiler knows that in methods, if you write a name of a variable you declared in the class of the object, that is the variable to use (if you didn't write a conflicting declaration in the method, of course).

You also should not pass a std::vector variable by value (that means, not using a pointer or, preferably, a reference). Why? Because your program needs to make a new copy of that vector. That means it must manually copy all the objects (in your case, tiles) your std::vector stores.
In fact, if you think about it, what should the Entity know? It should know on which map it is and its position. If you implement the Map class (which should probably have a vector of tiles), you can use something like

void Entity::turning(char facing1) {        
//not sure what THIS code does, but it is yours, so I won't modify it (except showing the 'OOP way')
    if (is_swing_hoe == false) {
        if(facing != facing1) {
            facing = facing1;
            wait_time = 0;
        }
        //suppose that map can extract all the needed information from the entity using getters
         else if (map->can_pass(this, facing1)&& wait_time > 3) {
            frame = 1;
            move_animation = true;
        }
    }
}
Voila! The function is much more readable. As a rule of thumb, you should always think twice before starting working on a new feature. How will I represent it? Who (which class) will use it? How should I implement it? If you ask and answer all the questions that come to your mind, you will find yourself writing much cleaner (and bug-free) code.

[quote name='ifthen' timestamp='1357125503' post='5016644']
Please read a book about C++. You are calling a METHOD (as opposed to function). A method belongs to an object. Therefore, you can access a pointer to object you are calling your method from using keyword 'this'. So you can write
[/quote]

I did read a book but I started getting confused so I started making this game so I could get some experience in order to understand the book better. This was a really helpful post thank you.

Please read a book about C++. You are calling a METHOD (as opposed to function). A method belongs to an object. Therefore, you can access a pointer to object you are calling your method from using keyword 'this'. So you can write


void Entity::turning(char facing1, vector<Tile> mv) {
    if (this->is_swing_hoe == false) {
                            if(this->facing != facing1) {
            this->facing = facing1;            this->wait_time = 0;
        }
        else if (this->can_pass(this->facing,mv,this)&& this->wait_time > 3) {
            this->frame = 1;            this->move_animation = true;
        }
    }
}
and 'this' will correspond to 'hero' if you call it like

hero->turning('d',mv);
Even better, you can remove all the 'this->' from above code. Your compiler knows that in methods, if you write a name of a variable you declared in the class of the object, that is the variable to use (if you didn't write a conflicting declaration in the method, of course).

You also should not pass a std::vector variable by value (that means, not using a pointer or, preferably, a reference). Why? Because your program needs to make a new copy of that vector. That means it must manually copy all the objects (in your case, tiles) your std::vector stores.
In fact, if you think about it, what should the Entity know? It should know on which map it is and its position. If you implement the Map class (which should probably have a vector of tiles), you can use something like

void Entity::turning(char facing1) {        
//not sure what THIS code does, but it is yours, so I won't modify it (except showing the 'OOP way')
    if (is_swing_hoe == false) {
        if(facing != facing1) {
            facing = facing1;
            wait_time = 0;
        }
        //suppose that map can extract all the needed information from the entity using getters
         else if (map->can_pass(this, facing1)&& wait_time > 3) {
            frame = 1;
            move_animation = true;
        }
    }
}
Voila! The function is much more readable. As a rule of thumb, you should always think twice before starting working on a new feature. How will I represent it? Who (which class) will use it? How should I implement it? If you ask and answer all the questions that come to your mind, you will find yourself writing much cleaner (and bug-free) code.

Okay another question. I am implementing your suggestions but I have a problem. I do not know if it would be efficient for me to include the data type Map as a variable in Entity.

Please read a book about C++. You are calling a METHOD (as opposed to function). A method belongs to an object. Therefore, you can access a pointer to object you are calling your method from using keyword 'this'. So you can write

I did read a book but I started getting confused so I started making this game so I could get some experience in order to understand the book better. This was a really helpful post thank you.

If the book got you confused you probably want to write something less complex than a game ;) If its a decent intro book it should have exercises you can work with.. The book will give you answers to all these questions and a lot more and you will understand it on a much better level.

This topic is closed to new replies.

Advertisement