Optimizing mathematical index calculation function I have made a function which calculates the index of a point to which an arbitrary point on a polygon made of XY points belong.

This is a visual representation:



And this is the function I made:

stock GetNodeIndexFromPolygonIndex(polygonid,Polygon_Size)
{
    new polid = (polygonid - (polygonid % 2));
    new mid = Polygon_Size/2;
    if(polid &gt; mid)
    {
        polid /= 2;
        return (mid - (++polid));
    }
    else
    {
        polid /= 2;
        if(polid == 0)
        {
            return 0;
          }
        return --polid;
    }
}


Is there anything I can optimize here?  This function is going to be called ~2000 times in the worst case in one run on a single threaded application. I would like this to be as optimal as possible.  Is it already?
First, I do not know anything about PAWN.

Does it have a profiler? Can any profiler be used? If yes, probably use it.
If no, write at least some test units to measure execution time.

I will assume typical language elements. I will assume polygonid &gt; 0 and Polygon_Size &gt; 0, because I do not know (and did not find in short time) the behavior of / and % for negative numbers.

As far as I understood, there is a virtual machine between compiler and execution. This makes things a little bit more complex, but well, we will assume that nothing special happens there.

Some of the optimizations could change nothing, because the compiler already does it. I can not predict or test it.

That said, I will choose line after line. I do not know if you can change the algorithm, because like Cygal I do not understand the exact purpose.



new polid = (polygonid - (polygonid % 2));


This makes polid the next smallest even number? % is rather costly, you could either do a polygonid &amp; 1 instead of polygonid % 2 or new polid = polygonid &amp; (max_value - 1) which will set all bits, but the last one to zero. max_value - 1 should be precalculated.



new mid = Polygon_Size/2;


Change to: new mid = Polygon_Size &gt;&gt; 1 This will be done most probably by the compiler anyway, but we do not know, so lets try it.



polid /= 2;


This is calculated in both branches. It could help to do it before the branching:

new polid_half = polid &gt;&gt; 1;
...




return (mid - (++polid));


This depends on the language details. It could be that ++polid as preincrement operator will load polid, update it by one, and store polid back. We do not plan to use the modified polid, so we could try return (mid - polid + 1) assuming that ++polid is not some magic fast special instruction compared to the normal +.



    if(polid == 0)
    {
        return 0;
    }


This does only happen if polygonid is 0 or 1. If this happens a lot, you should return immediately at the beginning, saving all the rest:

if (polygonid &lt; 2 )  //assuming polygonid &gt; 0
    return 0;


And remove the check inside the else branch.



    return --polid;


Same as before, it could be better to return polid - 1



Depending on the branch prediction handling, it could be better to have only one return point, not one in every branch. You could introduce a return value and set it according to the current logic.



I would try one change after the next and profile every step. All together, it could be:

stock GetNodeIndexFromPolygonIndex(polygonid,Polygon_Size)
{
    if (polygonid &lt; 2 )  //assuming polygonid &gt; 0
        return 0;
    new result = 0;
    new polid = polygonid &amp; (max_value - 1); //polid is a bad name
    new polid_half = polid &gt;&gt; 1;
    new mid = Polygon_Size &gt;&gt; 1;
    if(polid &gt; mid)
        result = mid - polid_half + 1;
    else
        result = polid_half - 1;
    return result;
}