Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

As an example, I have 3 different loops that are executed in certain conditions. I want to know if there's any way short of something like this:

if(day)
   x++;
else if(night)
   y++;
else
   z++;

Avoiding the continuous if checks, because I know under what conditions they will be executing... do I make myself clear?

I've thought of something along the lines of starting to execute a loop under the said x or y conditions, like so:

if(day)
 loopX();
else if(night)
 loopY();
else if(something else)
 loopZ();

But by doing this I'll effectively have to do checks for when to exit the loops, which ends up being the same, right?

I want to be able to say: "Start doing this!", and then eventually, at my discretion, "Now start doing this, instead!", without constant polling of conditions!

For example, were I currently in the "something else" state, I'd be doing 3 if checks every frame just to enter the loop! If I had something like 100 states, and was on the 100th, I would be checking 100 conditions just to get to the loop I want to execute!

A pratical game programming example: every frame, I do collision checking. Suddenly, I want to stop doing the collision checking. I do not want to have it check an if(collideStuff), I want it to straight out not do it.

void gameloop() {
   movestuff();
   something();
   collision(); // this would suddenly not have effect, as if it weren't there
}
share|improve this question
    
-1 To a bunch of answers for over-engineering, the question is about performance, not how to stuff code with complex OO structures that does a whole lot of other things than improve performance. They may have different benefits, but that is kind of off topic. –  eBusiness May 11 '13 at 20:35
    
Not sure where to put it: the closeste thing I've found so far to what I wanted, is this: stackoverflow.com/questions/122407/… I'd create an interface, TimeOfDay(), and instantiate it according to which function I wanted, = new TimeDay(), = new TimeNight(), etc. This way of doing it though would be very sloppy, no? Lots of interfaces and all. –  GigaBass May 11 '13 at 22:13
1  
I'm confused, it seems the obvious answer is that he should use a state machine. –  ClassicThunder May 12 '13 at 0:24

6 Answers 6

up vote 4 down vote accepted

A switch statement, at a very low level, is extremely efficient at this. The compiled code will include a static lookup table in the machine code that will require only one step to go to the correct code block, independent of the number of conditions. Be sure to use best practice with it at all times, (breaks and defaults and yada yada...). My java muscles are very atrophied, but I bet it enforces those rules by default.

It seems to me that you are exercising premature optimization. If you are really need this degree of performance, and reducing the total number of if statements is your bottleneck, then you need to stop using java.

share|improve this answer
    
Nothing concrete, just one of those "riddles" I've never solved by myself and decided to ask. I had no idea that the switch worked differently, that's good to know, thanks! However, the question is not supposed to be turned into the if/switch thing, but making something change it's behaviour without having to pool if's constantly. It would be ideal if there was something such as function pointers in java, where I'd do something like function = functionX(); which I believe exists in C/C++, but to what I've searched, there doesn't seem to be? –  GigaBass May 11 '13 at 19:48
2  
For methods on how to imitate function pointers in java, you could try some of the suggestions here: stackoverflow.com/questions/122407/… –  Gigggas May 11 '13 at 20:05
    
Whether a switch statement end up any different than an if chain when compiled depend on the compiler and the exact code in question. I wouldn't be surprised to see some compilers being able to treat a suitable if structure with pointer-foo like it was a switch statement. –  eBusiness May 11 '13 at 20:25
    
For who reads this in the future, a simple explanation on why Switch can be faster than Ifs: artima.com/underthehood/flowP.html –  GigaBass May 11 '13 at 21:40

The only way to eliminate checks is to use hardware interrupts.

Then you can write an infinite loop which assumes that it's forever daytime: it does not waste a single cycle checking that day has turned into night.

This loop is executed by a dedicated thread.

When day turns to night, a hardware interrupt goes off. The interrupt service routine responds by placing a breakpoint into the top of the loop executed by the daytime thread and then returns from the interrupt.

When the daytime thread reaches the top of the loop, the breakpoint triggers a software interrupt. (Again, the thread is not checking anything: the hardware is).

That software interrupt then removes the breakpoint and puts the daytime thread to sleep, and makes the nighttime thread runnable.

share|improve this answer

Why not go for a polymorphic approach where your logic is separated into objects with an update function?

You then add these objects to a list and simply loop over this list to update all. You can give each number a priority so that when you add an object to your list you can sort them easily so that you're sure each object is updated in the right order/

If you wan't to take out a system you simply take it out of the list.

public abstract class LogicObject{
  int priority = 0;
  abstract  void update(float dt);
  void setPriority(int value){priority = value}
  int getPriority(){return priority;
 }

-

public Collision extends LogicObjects{

  //Add more properties

  @Override 
  public void update(float dt){
     //updatecollision here
  }

}

-

 Collision collision = new Collision();
 collision.setPriority(3);



 private List<LogicObjects> gameLogicList = new ArrayList<LogicObjects>();
 gameLogicList.add(collision);     

 //sort your list on priority

 //somewhere in your main loop
 for(int i;  i < gameLogicList.size(); i++)
 {
    gameLogicList[i].update();
 }

Like sean said, working with events to trigger when something should or should not be used is an elegant way of doing it.

share|improve this answer
    
That's some good insight I hadn't thought of for game-design, thanks! –  GigaBass May 11 '13 at 21:44
    
I got a downvote. Can that person at least explain why? –  Sidar May 11 '13 at 22:36
1  
@Sidar You are uncritically introducing a lot of extra complexity. Without a more detailed task description you can't know if any of this would actually have a positive effect on performance. What I see here is a larger and more complex code base, slightly higher memory consumption and some unknown performance change. All this might be a part of an okay answer if it actually dealt with explaining the factors that decide how big the performance benefit/loss is. –  eBusiness May 11 '13 at 23:11
    
@eBusiness that's rather ironic. You make it sound like it's going to tear down performance, premature optimizations just by an idea. He looked for a way to opt out of the if/else clauses and I gave him one. How he plans to use it is up to him. How he plans to optimize it is up to him. I merely gave him an idea on a polymorphic solution. Nothing more, nothing less. I had no intention of giving him an "optimized" solution, such thing doesn't work at the stage he is in. So you can't talk about performance impact either. In the end it's up to him how he decides to adopt this idea. –  Sidar May 11 '13 at 23:20

Prudence

First of all, if you have an if statement that is run once per game loop, don't bother trying to optimise it away, your development time and the extra code complexity is always better spent somewhere else. If you have an if statement that is run 1000 times per game loop, it is probably not worth it either unless you already done all the big things and still need better performance.

Getting rid of some branching

That said, there are times when if statements make a serious performance impact. Especially situations where branch prediction fails (and it often does that a lot) they can be surprisingly costly. One of the best things you can do about "small" if statements is to rewrite them into arithmetic expressions. Instead of day and night being boolean variables you could make them integers and store 1 or 0 instead of true or false. (Note that in some languages true and false are basically treated as plain numbers, that makes this kind of code a bit more straight forward.)

Then you could simply write:

x+=day;
y+=night; //(assuming day and night are exclusive)
z+=1-(day|night);

Assuming that the compiler hasn't already decided on a similar optimization (which is reasonably probable, but you never really know with compilers, they behave odd at times) this code will be way faster.

Code like this is in general harder to both read and write than the equivalent if structure, don't use it in production unless it really makes a difference.

Function pointers for optimization

Function pointers can be a smart tool, but beware that your code when calling a function through a pointer needs to dereference that pointer. It is not much, but there is a little extra overhead involved. A worse consequence of trying to switch in different versions of a function is that it probably increases the code footprint. More code use more cache, and as a result cache misses become more frequent. The performance hit of a few extra misses may not be much, but if the gain from including the extra code in the first place wasn't a lot either the overall gain may in fact be a loss. Note that benchmarking this stuff can be really hard, the performance of the exact piece of code that was "optimised" may be better while the performance of the whole application is worse as the extra cache misses may hit anywhere.

share|improve this answer
    
Yeah, this popped up in my mind because the way I was thinkering up some mechanisms for my to-be-game, I'd be making very very heavy use of constant ifs per-object update. About the function pointers part: this is java, what are you considering to be function pointers? –  GigaBass May 11 '13 at 21:53
    
Also, the x+=day; y+=night; //(assuming day and night are exclusive) z+=1-(day|night); bit: this would work for simple ifs incrementing/decrementing variables, but what was intended here was something "complex", as in, more than simply incrementing variables. –  GigaBass May 11 '13 at 21:55
    
@GigaBass This question/answer that you found yourself seems to describe function pointers in Java. stackoverflow.com/questions/122407/… At least it should compile down to something similar to function pointers in C, so performance considerations should be similar. –  eBusiness May 11 '13 at 22:37
    
@GigaBass If the code inside an if statement is complex the if statement itself probably isn't a big performance issue. There is loads of other things that might improve performance, but it really depends on the specifics of the job. –  eBusiness May 11 '13 at 22:49
    
Also true, hadn't thought about that. –  GigaBass May 12 '13 at 0:25

Your second loop example is flawed. You will never want to write code like that because there are many common parts of your game that must run on each main loop iteration. More likely you'd end up with something like:

MainLoop():
  while not_quit:
    PumpOSMessages()

    PreFrameCommonUpdate()

    if is_day:
      UpdateDay()
    else if is_night:
      UpdateNight()

    PostFrameCommonUpdate()

Only one loop. Your logic is split into functions that handle a single iteration of loop.

You could consider using a Finite State Machine in place of the explicit conditions. Each of your special loops could be a single state. Every state has some code that is run each iteration of your game loop, let's call it update. Each State also has a way to transition to another state, which is the check you speak of.

You can organize your code such that these checks are in their own methods on each state object. E.g., your DayState might be (in pseudocode):

class DayState:
  void Update():
    // do your day loop code here once; Update is itself called in a loop

  State NewState():
    if should_be_night:
      return new NightState
    else
      return nil

Now on each iteration of your loop, the current state's Update is called, then NewState is called, and if it returns a new state, the state is switched. You can also then add method for transitions so special code can run when Day ends or Night begins and so on.

PreFrameCommonUpdate()

current_state->Update()
new_state = current_state->NewState()
if new_state is not nil:
  current_state->End()
  current_state = new_state
  current_state->Begin()

PostFrameCommonUpdate()

You can now add new states and transitions much easier than with a bunch of hard-wired conditions everywhere.

A second approach (which can be combined with the first) is to use events. If you have some other system which is tracking time of day, it will know when day transitions to night. It can emit a "EndDay" event that interested systems listen to. You will probably find that your main loops for day/night are very similar and that only some specific systems will change, e.g. maybe your MonsterSpawner changes what monsters it spawns. If it listens for EndDay and EndNight, it can change its active list of monsters to spawn from when it receives the event and doesn't need to check each loop iteration.

spawn_system->RegisterEvent('EndDay', time_system)
spawn_system->RegisterEvent('EndNight', time_system)

while not_quit:
  // might cause things to happen in other systems via events
  time_system->UpdateDayNightCycle()

  // uses current state to decide what to spawn
  spawn_system->MaybeSpawn()

In general, though, if you're just checking a few conditions each iteration of you main loop, you're fine. Your only worry should be whether the code is easy to understand and modify. There's no reason to be afraid of if-checks at such top-level code (doing an if-check inside some inner loop run 100,000 times per frame is another story).

Without knowing specifically what you're doing, I would suggest keeping the single loop and just put if-checks where the behavior needs to change. Making multiple loops is likely just going to result in a lot of redundant code for no real gain. Split your code up into logical modules to start and see how much flexibility that gains you.

share|improve this answer
    
I should take a look at state systems sometime around, good point. And yes, the example was sort of flawed but it gets the point across :) –  GigaBass May 11 '13 at 22:01

As a possible alternative, you might consider a job system. You would create jobs/commands/tasks -- essentially, bundles of information that tell you what and how to execute to e.g. do collision checking -- and schedule them for the subsequent frame. Each frame you would build the list of things you'd want to do for next frame, possibly including dependencies between the jobs (a task graph, loosely).

Note that this will have far more overhead -- both in code size and in execution time -- than a switch or other branch-around mechanism, generally speaking.

However, it does allow you to do more interesting things later: you can support parallel job execution, or even possibly distributed job execution (across a network, or across CPU and GPU, or other things of this nature); you could record info about what jobs executed for profiling and/or state changes for replay purposes.

If I know all the dependencies in my collision job/task, for example, I suddenly might run it concurrently in parallel with my sound task, or my particle VFX task, or what-have-you.

If you don't want something to execute, remove it from the task list/graph, or simply don't add it in the first place if you're building the list/graph each frame.

Structuring jobs/tasks in this way can have other maintainability benefits -- you're forced to more carefully consider your API boundaries and how data flows from system to system -- but on the other hand it's likely to be a performance loss for simple code, and the increase in complexity can be a burden on maintenance or introducing new programmers.

This is probably entirely overkill for your needs at the moment, I just wanted to put an alternative here.

If you're curious, there are plenty of interesting resources out there, e.g. the GDC Vault Task Graphing in Mortal Kombat (this is behind an expensive paywall, but the talk has been given at a few places, I think including GameFest, so the slides ought to be around somewhere -- I'll try to dig them up and return to edit this post). These are all big systems, but you can definitely pull little tidbits that are useful for even small projects.

share|improve this answer
    
That's sort of on the wave of what Sidar said, a good alternative, would also allow me to use threads, but yeah, it'd be a pretty big overkill at this point :) And I'll try look up those slides aswell! –  GigaBass May 11 '13 at 21:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.