ID:153597
 
I'm not quite sure how efficient the different mathematical/comparative functions and operators are -- I'd undoubtedly be taught this in a course for a degree in Computer Science, but I don't have such a course handy. (Still have to finish off my math upgrading before I can get automatically accepted into university -- though I figure I might as well drop an application off for next year, and get myself a full-time job (I can handle it) to pay for the tuition... wow, am I ever getting off the topic at hand.)

My basic experience goes (in order from most expensive to least expensive):

**
log()
/
, <<
*
--
-=, &=
-, &
!, ~
&&, ||
max(), min()
=, <=, !=
==, <, >
++
+=, |=
+, |
=


If you see any errors, don't hesitate to correct them.


One question I have: since dividing is just multiplying a reciprocal, does that mean that using "num * 0.5" would be more efficient than "num / 2.0"? (Floating point math in both instances.)
First off instead of x/2 you could use x>>2 =] (then again don't they convert to integers for this and if so I guess it ruins the idea :/ )

Although there MUST be a website for the standards about thius. Did you try a google search? Also min/max are procedures... and I don't see an explicit procedure slot on that list (technically they are probably usually evaluated first)
In response to Exadv1 (#1)
x>>2 would be x/4 anyway; the correct equivalent to x/2 is x>>1.

Lummox JR
Spuzzum wrote:
I'm not quite sure how efficient the different mathematical/comparative functions and operators are -- I'd undoubtedly be taught this in a course for a degree in Computer Science, but I don't have such a course handy. (Still have to finish off my math upgrading before I can get automatically accepted into university -- though I figure I might as well drop an application off for next year, and get myself a full-time job (I can handle it) to pay for the tuition... wow, am I ever getting off the topic at hand.)

My basic experience goes (in order from most expensive to least expensive):

**
log()
/

This looks right so far.

, <<

Nope, these are among the least expensive at the machine level. Shifting bits is a very very simple operation.

*

This should be a little less expensive than / or at best equal.

--

This should be on the same level as ++, and again it's one of the least expensive operations--it should be very inexpensive in BYOND as well.

-=, &=
-, &

The - and & operators aren't related; addition and subtraction go together, and OR and AND and XOR go together. You've mixed them up here. I don't think it's particularly wise either to bring assignment operators into this, because they're a separate topic. An assignment-and-operation should be more efficient than the two separately, but the speed will depend on the operator. Mostly. In BYOND you also have the issue of lists, which muddies the waters, because += and -= operate on the original list whereas + and - make a copy.

+ and - should be the next tier down from * and /, and the bitwise operators | and & and ^ should be less expensive than that. In BYOND, this might work in reverse since it has to do an integer conversion.

!, ~

I think the efficiency of ! may depend on the language, but it should be one of the lesser operations.

The ~ operator should go with the bitwise operators. It's in a different category than !.

&&, ||

These would be similar to ! in what they do, and in expense. However in a language like C they shortcut some tests, which requires a conditional jump, which means they can be just a tad more expensive.

max(), min()

As a comparison of just two values these would be conditional operations, which means they essentially work out to (a>b?a:b) and (a<b?a:b). In BYOND you can compare multiple values. But these would go much higher up the list in any case, because of the reliance on another conditional test.

=, <=, !=
==, <, >

All of these should have an equal cost. In a language like BYOND however some additional work might be needed for certain equal/not-equal comparisons with objects.

++

This is actually quite low, alongside --, and should cost less than + because it's usually a machine instruction.

+=, |=
+, |

Again this is a mix of categories.

=

Assignment may be the least expensive operation, except when you involve lists.

Incidentally you forgot completely to consider the costs of list operations.

One question I have: since dividing is just multiplying a reciprocal, does that mean that using "num * 0.5" would be more efficient than "num / 2.0"? (Floating point math in both instances.)

I believe there's a very very very slight performance edge, yes.

In BYOND, my tests seem to indicate that the bit shift operators are just a hair faster in spite of the integer conversion. If you're working with small integers and don't care about remainders, stick with those.

Lummox JR
In response to Lummox JR (#3)
, <<

Nope, these are among the least expensive at the machine level. Shifting bits is a very very simple operation.

The rest of the post I've digested, but this one came up on the radar.

Doesn't shifting bits require 16 cycles to execute -- one for each bit? (Of course, I'm oblivious to how many cycles the others require, so 16 cycles could be a low bound for efficiency.)
In response to Spuzzum (#4)
Doesn't shifting bits require 16 cycles to execute -- one for each bit? (Of course, I'm oblivious to how many cycles the others require, so 16 cycles could be a low bound for efficiency.)

Well I only worked with ASM for an 86HC11 but on that a bit shift takes 2 clock cycles and multiplication/division with integers took a variable amount with a minimum of 32 clock cycles. Even if you need to shift 16 times(which would be kinda pointless as you'd lose all data) it'll still probably be faster. Take into accout floating point math and it's probably even worse, so yeah bit shifting is faster depending on how long it take BYOND to do the conversion to make the data an int.

[edit] It takes 2 cycles for each shift, so if you only shift 2 times it's 4 cycles. The entire shift is handled in the hardware itself so it only takes one cycle to shift and one to clear the data and address bus.

[edit2] Oh and when I mean it's done in hardware I mean it's physically wired to handle that operation in one cycle instead of having it cycle through one hardware process 16 times which would be considered handling it with software :).
In response to Spuzzum (#4)
Shifting would never have taken 16 cycles; most integer multiplication doesn't even approach that. In modern processors it's a 1-cycle operation, tops.

Lummox JR