Search code examples
c++optimizationsdl

How to reduce the amount of checks of similar code blocks?


I do not seem able to improve the following code:

    if(state[SDL_SCANCODE_M]){
        if(_ball.velocity.x < 0)
            _ball.velocity.x -= 20;
        else
            _ball.velocity.x += 20;

        if(_ball.velocity.y < 0)
            _ball.velocity.y -= 20;
        else
            _ball.velocity.y += 20;
    }

    if(state[SDL_SCANCODE_L]){
        if(_ball.velocity.x < 0)
            _ball.velocity.x += 20;
        else
            _ball.velocity.x -= 20;

        if(_ball.velocity.y < 0)
            _ball.velocity.y += 20;
        else
            _ball.velocity.y -= 20;
    }

They are pretty similar, but the operations are the opposite.

Is there any best practice or technique that allows to improve these kind of situations?


Solution

  • You can pre-compute some factor so to inverse the sign regarding the conditions.

    Here is an example:

    int xCoef = (_ball.velocity.x < 0) ? -1 : 1;
    int yCoef = (_ball.velocity.y < 0) ? -1 : 1;
    
    if(state[SDL_SCANCODE_M]){
        _ball.velocity.x += xCoef * 20;
        _ball.velocity.y += yCoef * 20;
    }
    
    if(state[SDL_SCANCODE_L]){
        _ball.velocity.x -= xCoef * 20;
        _ball.velocity.y -= yCoef * 20;
    }
    

    A more compact (branch-less) version that is a bit less clear (but probably more efficient) is the following:

    int xCoef = (_ball.velocity.x < 0) ? -1 : 1;
    int yCoef = (_ball.velocity.y < 0) ? -1 : 1;
    int mPressed = state[SDL_SCANCODE_M] ? 1 : 0;
    int lPressed = state[SDL_SCANCODE_L] ? 1 : 0;
    _ball.velocity.x += (mPressed - lPressed) * xCoef * 20;
    _ball.velocity.y += (mPressed - lPressed) * yCoef * 20;
    

    Note that if state is a boolean array, you do not even need to use a ternary since booleans can be directly converted to 0-1 integer values.