Optimizing Code

Blitz3D Forums/Blitz3D Programming/Optimizing Code

Craig H. Nisbet(Posted 2005) [#1]
I'm to the point where I need to optimize my code. Anyone have any suggestions as to what types of code are typically slow?


splinux(Posted 2005) [#2]
http://www.blitzcoder.com/cgi-bin/articles/show_article.pl?f=maherfarag09192002175711.html


Matty(Posted 2005) [#3]
Linepicks/Camerapicks/Entitypicks


Writepixel(fast),Readpixel(fast),plot,getcolor - when performed on large areas of the screen (or smaller areas on slower machines)

Nested for loops with large numbers of iterations in each loop. For example if you were to do something like this every frame it would have an impact:

For Creature.CreatureList =each CreatureList
   For OtherCreature.CreatureList=each CreatureList
;assuming many hundreds/thousands of creatures in the list 

;place a decent number of calculations here such as checking if each creature can see each other or is within a certain distance.  

   next
next


Also, using vertexcoords, vertextexcoords, vertexcolor commands on meshes with many vertices will affect speed regardless of how many vertices you actually alter.

Using collision method 2 (ellipsoid - polygon) can slow things down if the object using the polygon collision detection is complex. It can be better, for example with a level, to create a nice detailed level as normal but to create a much simpler mesh which is hidden using entityalpha mesh,0.0 and using that for collision detection instead.

Using many sprites (3d) instead of single surface quads. Obviously the more powerful the system the more sprites that you can get away with using - so a small number (define small?) should not be a problem overall but many of them can cause a performance hit.

Using hideentity/showentity when an entity is out of the camera frustrum is of no use - but using hide/show entity when an entity is out of view but in the camera frustrum can reduce overdraw (drawing same pixels twice). However if you start using linepicks or other slow line-of-sight checks to determine this before hiding then that will slow things down. If you are going to hide entities and show them based on Line of Sight then it can be worthwhile to precalculate zones where objects are visible to each other in your level, say in a 3 dimensional array for which each value represents a cube of the level and holds a pre-prepared list (perhaps using banks) of which other zones can 'see' each other.

Using text commands in 3d or using drawimage/drawblock commands in 3d mode with large images (once again - define large it all depends on the system you are aiming for).


WolRon(Posted 2005) [#4]
In the link that SpLinux posted, most of those speed improvements will have little effect unless they are run thousands of times per game loop. Don't get me wrong, they are faster, but most of the time, it's a waste of YOUR time to use those optimisations. Only bother with them if you ARE performing them lots of times.
Tips that fall into that category are:
1, 2, 8, 11, 12, 13, 16, 17, 19

Some of the tips are actually wrong (at least in this day and age, they are), such as:
4: most new graphics cards handle 24 & 32 bit better than 16
9: Doesn't appear to be:
image = CreateImage(800, 600)
start = MilliSecs()
For n = 0 To 100000
	z = ImageHeight(image)
	For x = 1 To z
		y = Rand(0, 1)
	Next
Next
Print MilliSecs() - start
FreeImage image

image = CreateImage(800, 600)
start = MilliSecs()
For n = 0 To 100000
	For x = 1 To ImageHeight(image)
		y = Rand(0, 1)
	Next
Next
Print MilliSecs() - start
FreeImage image

WaitKey
End
14: No improvement noted. Try it yourself.
15: The first example is better. If the X=1 comparison fails, then the Y=1 comparison isn't even performed. In the second example, both comparisons are ALWAYS performed. Now which do you think is faster? The following code compares them (and tip 16 as well)
;Tip 15 Ex. 1
SeedRnd 1
start = MilliSecs()
For n=0 To 10000000
	x = Rand(0, 1)
	y = Rand(0, 1)
	If x = 1
		If y = 1
			x = Rand(0, 1)
		EndIf
	EndIf
Next
Print MilliSecs() - start

;Tip 15 Ex. 2
SeedRnd 1
start = MilliSecs()
For n = 0 To 10000000
	x = Rand(0, 1)
	y = Rand(0, 1)
	If x = 1 And y = 1
		x = Rand(0, 1)
	EndIf
Next
Print MilliSecs() - start

;Tip 16
SeedRnd 1
start = MilliSecs()
For n = 0 To 10000000
	x = Rand(0, 1)
	y = Rand(0, 1)
	If x + y = 2
		x = Rand(0, 1)
	EndIf
Next
Print MilliSecs() - start

WaitKey
End
18: Wheres the speed increase?
SeedRnd 1
start = MilliSecs()
For n = 0 To 10000000
	x = Rand(1, 3)
	If x = 1 Then y = Rand(100)
	If x = 2 Then y = Rand(100)
	If x = 3 Then y = Rand(100)
Next
Print MilliSecs() - start

SeedRnd 1
start = MilliSecs()
For n = 0 To 10000000
	x = Rand(1, 3)
	Select x
		Case 1
			y = Rand(100)
		Case 2
			y = Rand(100)
		Case 3
			y = Rand(100)
	End Select
Next
Print MilliSecs() - start

WaitKey
End


Some Tips ARE right on, such as:
3, 5, 7, 10

And some Tips include some misinformation like:
6: GetColor is slow, but SO IS READPIXEL! Don't use EITHER if you can avoid them.
20: Goto is FAST!. Why not use it? I mean, if you're looking for optimisations why would you throw it out? A few Goto's in the correct places are not going to cause you any bugs. That being said, this is an optimisation that is rarely needed and falls into the first category I listed above.

Someone should update that page...

In fact, this has motivated me to write my own (unfinished)Speed Tips page...