code of the Ninja();

// in search of swift, efficient, and invisible code

2012-11-05

Prepare To Be Floored

This post is nothing too special or groundbreaking, but it might be of interest to anyone who is as huge of a nerd as I am.

I noticed long ago that Game Maker automatically rounds numbers and variables when they are used as array indices. So, for example array[3.6] is precisely equivalent to array[4].

I also noticed that the same thing happens when performing binary operations:

is precisely equivalent to . The same principle holds for ^ and |.

is precisely equivalent to . The same principle holds for .

Knowing this is certainly useful; it can rid your code of unnecessary calls to the round() function.

But I got an evil thought - what would happen if I tried bit shifting a number by zero, e.g. or ? Mathematically, a bit shift of zero should leave the number unaffected, but would Game Maker go ahead and round it anyway?

The answer is yes! is equal to 32. Therefore this code:

Has the identical effect as this code:

An interesting quirk; a titbit of trivia. So what?

Well, I suspected that it might be a faster operation than the calling of the round() function, and so I tested this hypothesis. The result?

Bit shifting by zero is twice as fast as using round(). Now, that function is hardly going to break the bank, but if you have code that relies on it heavily this is definitely something to consider with regard to optimisation.

For the same effect you could also with ~1, as in this code:

It also rounds the number much faster than round(), comparable to the speed of the bit shifting method. I just don't like the readability as much; the bit shift method > 0--> looks like it's knocking off digits past zero, which is a reasonable mnemonic for rounding.

This is all very well and good for rounding, but what about flooring or ceiling a number? This trick always rounds up with a fractional part of 0.5 or above, and rounds down below that. In Game Maker, you can use the floor() function to always round down, and the ceil() function to always round up.

You're in luck, because you can do code like this:

These will still be very nearly twice as fast as their function equivalents!

(EDIT: The above about flooring and ceiling isn't perfect; be sure to read my correction!)

Okay, so maybe in practice this will make your code more confusing and less readable, but like I said: "huge nerd". =P

No comments:

Post a Comment