Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
18 replies to this topic

#1 Walkerism   Members   -  Reputation: 108

Like
0Likes
Like

Posted 27 June 2011 - 06:43 AM

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?



Sponsor:

#2 braindigitalis   Members   -  Reputation: 230

Like
0Likes
Like

Posted 27 June 2011 - 06:49 AM

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

Games Currently In Development:

Currently rewriting Firework Factory - Casual Puzzler for PC in Direct3D 11. Latest Journal Entry.

 

 


#3 way2lazy2care   Members   -  Reputation: 782

Like
0Likes
Like

Posted 27 June 2011 - 06:55 AM

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.

#4 rip-off   Moderators   -  Reputation: 8540

Like
1Likes
Like

Posted 27 June 2011 - 07:14 AM

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.

#5 Walkerism   Members   -  Reputation: 108

Like
0Likes
Like

Posted 27 June 2011 - 07:26 AM

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.




#6 way2lazy2care   Members   -  Reputation: 782

Like
-2Likes
Like

Posted 27 June 2011 - 08:00 AM

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.

#7 JoeCooper   Members   -  Reputation: 338

Like
3Likes
Like

Posted 27 June 2011 - 08:56 AM

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...

too much of a tendency to use 'if' and 'while' loops, which I know is bad practice



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.

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.

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 ).



C++ uses "lazy evaluation". Say I have:

if(a && (x > x2) && (y > y2)) ... ;

Where 'a' is a boolean.

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?

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.

Other languages, like Java, do not use lazy evaluation. (See what I mean about platform?)

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. You can use the bool datatype to perform an store an evaluation.

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.

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.

#8 Álvaro   Crossbones+   -  Reputation: 13698

Like
0Likes
Like

Posted 27 June 2011 - 09:12 AM

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.

#9 way2lazy2care   Members   -  Reputation: 782

Like
2Likes
Like

Posted 27 June 2011 - 09:30 AM

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.

#10 JoeCooper   Members   -  Reputation: 338

Like
0Likes
Like

Posted 27 June 2011 - 09:34 AM

lolz, I know. Or even better: while(1) fork();

#11 rip-off   Moderators   -  Reputation: 8540

Like
2Likes
Like

Posted 27 June 2011 - 09:41 AM

JoeCooper's advice is good. I just wanted to point out the following:

Other languages, like Java, do not use lazy evaluation. (See what I mean about platform?)

What you are describing is most commonly called "short circuit evaluation". The term "lazy evaluation" is more often used in functional languages to mean expressions which are evaluated as late as possible, even allowing potentially infinite expressions to be described, so long as you are careful never to try and fully evaluate it. A classic example is a list of Fibonacci numbers, the expression is lazy such that a particular element can be evaluated, but you shouldn't try to do something like get the length of this list.

Java does use short-circuit evaluation on the operators &&, ||. According to the table in this article, all the mainstream languages that offer operators like &&, || do short-circuit evaluation on them.

This is a common idiom in Java (and most such languages), that avoids accessing an invalid object:
if(object != null && object.someCondition())
{
   // ...
}


#12 JoeCooper   Members   -  Reputation: 338

Like
0Likes
Like

Posted 27 June 2011 - 09:54 AM

Crickey! I was 99% sure I looked it up and I've written a few apps assuming it didn't work that way. I've got code like

if(object != null)
if(...)
{
 ...
};

Everywhere.

Must've been cause I got the term wrong. Thanks for the note about that!

#13 SiCrane   Moderators   -  Reputation: 9630

Like
1Likes
Like

Posted 27 June 2011 - 09:57 AM

all the mainstream languages that offer operators like &&, || do short-circuit evaluation on them.

Assuming that they aren't overloaded anyways. In C++ if you overload && or || then short circuit evaluation no longer applies. Some languages don't allow operator overloading on logical and and logical or for this reason.

#14 landlocked   Members   -  Reputation: 103

Like
0Likes
Like

Posted 27 June 2011 - 10:12 AM

There is something to look out for though if you feel like you're being too reliant on conditional statements. Make sure your code is separated into neat routines that only address a single task and Don't Repeat Yourself (aka the dry principal). So, if you have massive routines with lines and lines of code with many many branches of possible execution you are quite probably violating the DRY principal and should refactor. It makes your code more readable and maintainable and all that jazz and even more performant a lot of times as you likely won't need as many clock cycles to get through your various branches to execute the code you need to. All the above advice is good. This is just an important aside.
Always strive to be better than yourself.

#15 rip-off   Moderators   -  Reputation: 8540

Like
0Likes
Like

Posted 27 June 2011 - 10:27 AM

Assuming that they aren't overloaded anyways.

I would hope not, not for such operators anyway! Good catch though.

#16 A Brain in a Vat   Members   -  Reputation: 313

Like
0Likes
Like

Posted 27 June 2011 - 10:33 AM

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.

I think you're probably not using functions enough.

I don't too often write if statements that compound that many checks together, but that doesn't mean my code isn't checking for all the same things yours is. My code is just structured more like this:
void main()
{
	if (someBool == true)
	{
		Func1();
	}
}

void Fun1()
{
	if (someThing.x > x && someThing.y > y)
	{
		Func2();
	}
	else
	{
		Func3();
	}
}

Just try to write small functions which perform individual tasks. A function should be in charge of doing only one thing, and should usually be small (it should fit entirely on your screen).

#17 way2lazy2care   Members   -  Reputation: 782

Like
0Likes
Like

Posted 27 June 2011 - 10:38 AM

This is a common idiom in Java (and most such languages), that avoids accessing an invalid object:

if(object != null && object.someCondition())
{
   // ...
}


Interesting factoid from the google talk. To avoid this situation, you should return a null object rather than a null reference to avoid having to do this check. Not sure on the performance impact of this as I have literally just heard it in the google talk, but it seems like solid advice to me.

#18 Walkerism   Members   -  Reputation: 108

Like
3Likes
Like

Posted 27 June 2011 - 12:50 PM

I have to say guys, this is honestly some of the most informative and helpful advice I've read since I started programming. Seriously, you've given me much to think about and put a lot of ideas to rest. I'll start to think in functions to make my code more approachable. As for optimizing, I'll keep brush that worry aside XD

Cheers everyone, I'll be coming back to this thread often to make sure my code doesn't disagree with the guidelines you've collectively written.



#19 JoeCooper   Members   -  Reputation: 338

Like
2Likes
Like

Posted 27 June 2011 - 01:10 PM

Oh yeah, and don't actually run the while(1) fork(); code I mentioned earlier, ever.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS