I need advice on breaking a bad habit; 'if' & while reliance' (C++)

Started by
17 comments, last by JoeCooper 12 years, 9 months ago
Hi guys,

I'm starting to notice what I'm calling a problem early on. Whenever I create code I have too much of a tendency to use 'if' and 'while' loops, which I know is bad practice. The problem lies in that I'm still learning the syntax in C++, but at this stage I keep thinking in terms of of 'if' or 'while' which is resulting in needlessly complicated code. Can anyone offer me some advice on how to think outside of these two notions?

Advertisement
Can you maybe give an example of how you think you are misusing the language then we may be able to advise...

Hi guys,

I'm starting to notice what I'm calling a problem early on. Whenever I create code I have too much of a tendency to use 'if' and 'while' loops, which I know is bad practice. The problem lies in that I'm still learning the syntax in C++, but at this stage I keep thinking in terms of of 'if' or 'while' which is resulting in needlessly complicated code. Can anyone offer me some advice on how to think outside of these two notions?


This kind of optimization is pretty premature. These days compilers are generally smarter than you, so it's better to wait until you have a bottleneck before worrying about optimizing anything.

edit: to clarify I meant optimize anything at this minute a level, not optimize in general.
Where did you hear that this is bad practice?

The only thing I can think of is nested use of loops and conditionals. To write clear code, replace such use by factoring out the logic into helper functions.

Can you maybe give an example of how you think you are misusing the language then we may be able to advise...


I'll dig around and try to find a good example, off the top of my head though (and where the concern lies) is I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ). It makes it hard for me to build values that are relevant.




This kind of optimization is pretty premature. These days compilers are generally smarter than you, so it's better to wait until you have a bottleneck before worrying about optimizing anything.




That's quite comforting to know thanks, though I must admit I find learning easier when I'm aware of the steps taken ahead. I find enjoyment in being prepared for the road ahead, keeps me enthusiastic throughout the early stages when steps ahead have been made aware.



I'll dig around and try to find a good example, off the top of my head though (and where the concern lies) is I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ). It makes it hard for me to build values that are relevant.


If you are constantly checking the state of objects it's probably better to store the state and only check it's state when you want to check it.

This is still kind of a vague use case to optimize though. There are plenty of situations where it's perfectly acceptable and others where it may not be necessary. It's very much a case by case thing.
It's certainly not a bad habit or a problem in principle. Branching is one of the key features of this whole computer thing and loops are what you do whenever you want to perform an operation on a large number of entities.

Checking states of things, doing comparisons, validating actions against constraints... This is the work of a computer. This is its reason for being. It's what game software does.

Nevertheless, I will go over some things, but only after I go over three warnings. As a beginner, the instinct to ignore these warnings will be great. Stamp that instinct into a pit.

1) As a beginner, the number one thing you're learning is the bureaucratics of putting together game software. Things like how a whole game application fits together, how to use RAD tools to write tools, Model-View-Controller and Observer pattern and so on, how to integrate characters talking into a game loop, crap like that.

2) Optimizations heavily depend on the platform. By the time you've learned the above, the platform will have changed. I just wrote something on the iPad, and almost nothing I learned to make our Java application work well was useful. I referred to manuals provided by Apple to make it perform to spec. Java and iOS each required mountains of esoteric knowledge to make them perform.

Wasting time on platform ideosyncracies will prevent you from doing part 1. It is time wasted.

3) Use a profiler to learn what actually needs to be optimized, because you don't know what is actually challenging the computer.

Now then...

[color="#1C2837"]too much of a tendency to use 'if' and 'while' loops, which I know is bad practice[/quote]

[color="#1C2837"]In Java (and maybe C#?) it's common practice to use the instanceof and is operators to ask what an object is, and act accordingly.

[color="#1C2837"]There is an equivalent in C++ and it's considered bad practice. (I won't say how you do this, it's complicated.) If you find yourself making such decisions, ask yourself if you could be using a virtual method to accomplish this.

[color="#1C2837"]I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ).[/quote]

[color="#1C2837"]C++ uses "lazy evaluation". Say I have:

[color="#1C2837"]if(a && (x > x2) && (y > y2)) ... ;

[color="#1C2837"]Where 'a' is a boolean.

[color="#1C2837"]If a is false, than the rest of the statement will not be evaluated. Why not? Because the AND operator may only yield true if both operands are true. As soon as the machine knows that one of them is not true, it quits. Make sense?

[color="#1C2837"]So you follow, as a habit, the "common case first" principle. Which piece is most likely to fail? Put that first. It will reduce the likelihood that other segments will be evaluated superfluously. If you can't make a prediction, don't order them.

[color="#1C2837"]Other languages, like Java, do not use lazy evaluation. (See what I mean about platform?)

[color="#1C2837"]In some loops you may find that you're repeating an evaluation who's dependent variables do not change from one iteration to the next. [color="#1C2837"]You can use the bool datatype to perform an store an evaluation.

[color="#1C2837"]But just to reiterate, checking these things is literally what you're supposed to be doing. If you need to do a bounds check, do a bounds check.

[color="#1C2837"]If you're worried you might be doing this dozens of times... Try to realize that a typical game is running hundreds of thousands of vertices through all kinds of 4x4 matrix-vector multiplications and rasterizing a million+ pixels using custom "shader" software every frame. As a beginner, you do not have the art resources to make even the cheapest computer break a sweat.
I haven't found any code where there were more `while' statements than I would have liked. However, having lots of `if' statements if often a problem. Not because the code generated would be slow (that argument would certainly be a premature optimization, and besides it's probably not true), but because code without `if's is easier to read, easier to test and easier to maintain.

This Google talk is about coding without `if's. I highly recommend listening to it, even if you don't follow its advice. It will give you some good ideas on how to organize and test code.
[color="#1C2837"]As a beginner, you do not have the art resources to make even the cheapest computer break a sweat.


Open Blender3D -> Add Monkey -> Subsurf to level >100 -> convert to mesh -> blow up computer (I'm sure the computer would blow up as soon as you try to subsurf that much)

;)

Just playing devils advocate. I agree with everything you've said.
lolz, I know. Or even better: while(1) fork();

This topic is closed to new replies.

Advertisement