Tiny But Super Optimizations
#1

In this thread I'll point out some very small optimizations that can make a huge difference in speed in the long run.

Most of these are very minor, negligible speed differences. The point is THERE ARE DIFFERENCES. There are a lot of situations where these would help majorly. Sure these cases are rare, but they do exist and I've encountered them a lot!

Bare in mind, this thread is still no where near being complete.

I bet you didn't know that "+= 1" and "var = var + 1" were both twice as fast as "++", so read on.

(Note: lines preceded by a semi-colon in the assembly are comments.)

____________________________________________


Here is a great example to start us off.

Float vectors: Arrays vs Multiple Variables.
I've seen so many people doing things like this:
pawn Code:
new Float:t[3];
Instead of doing this:
pawn Code:
new Float:tX, Float:tY, Float:tZ
What's wrong with that? Well look here:
pawn Code:
tX = tY = tZ = 1;
This compiler turns that into the following assembly output:
Code:
    const.pri 1
    stor.s.pri fffffff4
    stor.s.pri fffffff8
    stor.s.pri fffffffc
While for this:
pawn Code:
t[0] = t[1] = t[2] = 1;
The compiler does this:
Code:
    addr.pri ffffffe8
    push.pri
    addr.pri ffffffe8
    add.c 4
    push.pri
    addr.pri ffffffe8
    add.c 8
    move.alt
    const.pri 1
    stor.i
    pop.alt
    stor.i
    pop.alt
    stor.i
I'm not going to walk you through the assembly, but I think it's obvious which one is better. It doesn't matter if you chain them or not, the arrays will always be slower. Just to prove my point here is the timing of each of these:
Quote:

Timing "accessing and setting singles"...
Mean = 136.00ns
Mode = 135.00ns
Median = 136.00ns
Range = 4.00ns
Timing "accessing and setting array"...
Mean = 233.00ns
Mode = 232.00ns
Median = 233.00ns
Range = 3.00ns

____________________________________________


Now for the rest of them.

  • Variable definitions: Chained Definitions vs Defining Each
    What people are doing:
    pawn Code:
    new tmp1;
        new tmp2;
        new tmp3;
        new tmp4;
        new tmp5;
    What people should be doing more often:
    pawn Code:
    new tmp1, tmp2, tmp3, tmp4, tmp5;
    Assembly for what people are doing:
    pawn Code:
    break
        push.c 0
        break
        push.c 0
        break
        push.c 0
        break
        push.c 0
        break
        push.c 0
    Assembly for what people should be doing more often:
    pawn Code:
    push.c 0
        push.c 0
        push.c 0
        push.c 0
        push.c 0
    So basically, the break's (';') are almost doubling the time it takes! Don't believe me? Well, look at the time comparison:
    Quote:

    Timing "new chain"...
    Mean = 114.00ns
    Mode = 114.00ns
    Median = 114.00ns
    Range = 2.00ns
    Timing "new each"...
    Mean = 221.00ns
    Mode = 222.00ns
    Median = 222.00ns
    Range = 3.00ns

    It's a shame that PAWN does this, but it is a fact we must face.
  • Setting Variables: Chain Assignments vs Assigning Each
    What people are doing:
    pawn Code:
    tmp1 = 17;
        tmp2 = 17;
        tmp3 = 17;
        tmp4 = 17;
        tmp5 = 17;
    What people should be doing more often:
    pawn Code:
    tmp1 = tmp2 = tmp3 = tmp4 = tmp5 = 17;
    Assembly for what people are doing:
    pawn Code:
    break
        const.pri 11
        stor.s.pri fffffffc
        break
        const.pri 11
        stor.s.pri fffffff8
        break
        const.pri 11
        stor.s.pri fffffff4
        break
        const.pri 11
        stor.s.pri fffffff0
        break
        const.pri 11
        stor.s.pri ffffffec
    Assembly for what people should be doing more often:
    pawn Code:
    const.pri 11
        stor.s.pri ffffffec
        stor.s.pri fffffff0
        stor.s.pri fffffff4
        stor.s.pri fffffff8
        stor.s.pri fffffffc
    So, 6 lines versus 15, which one is fastest?
    Quote:

    Timing "set chain"...
    Mean = 121.00ns
    Mode = 118.00ns
    Median = 119.00ns
    Range = 18.00ns
    Timing "set each"...
    Mean = 219.00ns
    Mode = 217.00ns
    Median = 217.00ns
    Range = 9.00ns

    6 lines, obviously. Start chaining your variable asignments if you are setting them to the same value!
  • If Lines: Chained vs Many
    What people are doing:
    pawn Code:
    if(tmp1 == 1)
            if(tmp2 == 1)
                if(tmp3 == 1)
                    if(tmp4 == 1)
                        if(tmp5 == 1)
                            {}
    What people should be doing more often:
    pawn Code:
    if(tmp1 == 1 && tmp2 == 1 && tmp3 == 1 && tmp4 == 1 && tmp5 == 1) {}
    Assembly for what people are doing:
    pawn Code:
    break
        load.s.pri fffffffc
        eq.c.pri 1
        jzer 3
        break
        load.s.pri fffffff8
        eq.c.pri 1
        jzer 4
        break
        load.s.pri fffffff4
        eq.c.pri 1
        jzer 5
        break
        load.s.pri fffffff0
        eq.c.pri 1
        jzer 6
        break
        load.s.pri ffffffec
        eq.c.pri 1
        jzer 7
    Assembly for what people should be doing more often:
    pawn Code:
    break
        load.s.pri fffffffc
        eq.c.pri 1
        jzer 1
        load.s.pri fffffff8
        eq.c.pri 1
        jzer 1
        load.s.pri fffffff4
        eq.c.pri 1
        jzer 1
        load.s.pri fffffff0
        eq.c.pri 1
        jzer 1
        load.s.pri ffffffec
        eq.c.pri 1
        jzer 1
    So by sight, it's the breaks (each if section this time) again!
    Quote:

    Timing "if chain"...
    Mean = 164.00ns
    Mode = 163.00ns
    Median = 164.00ns
    Range = 3.00ns
    Timing "if lot"...
    Mean = 230.00ns
    Mode = 228.00ns
    Median = 228.00ns
    Range = 16.00ns

    They are slowing us down more than we think!
  • Value Testing: Switch vs "If =="
    What people are doing:
    pawn Code:
    if(tmp == 2 ) {}
            else if(tmp == 5 ) {}
            else if(tmp == 8 ) {}
            else if(tmp == 11) {}
            else if(tmp == 14) {}
            else if(tmp == 17) {}
            else if(tmp == 20) {}
            else if(tmp == 23) {}
            else if(tmp == 26) {}
            else if(tmp == 29) {}
            else {}
    What people should be doing more often:
    pawn Code:
    switch(tmp) {
                case 2 : {}
                case 5 : {}
                case 8 : {}
                case 11: {}
                case 14: {}
                case 17: {}
                case 20: {}
                case 23: {}
                case 26: {}
                case 29: {}
                default: {}
            }
    Assembly for what people are doing:
    pawn Code:
    break
            load.pri 0
            eq.c.pri 2
            jzer 0
            jump 1
        l.0
            break
            load.pri 0
            eq.c.pri 5
            jzer 2
            jump 3
        l.2
            break
            load.pri 0
            eq.c.pri 8
            jzer 4
            jump 5
        l.4
            break
            load.pri 0
            eq.c.pri b
            jzer 6
            jump 7
        l.6
            break
            load.pri 0
            eq.c.pri e
            jzer 8
            jump 9
        l.8
            break
            load.pri 0
            eq.c.pri 11
            jzer a
            jump b
        l.a
            break
            load.pri 0
            eq.c.pri 14
            jzer c
            jump d
        l.c
            break
            load.pri 0
            eq.c.pri 17
            jzer e
            jump f
        l.e
            break
            load.pri 0
            eq.c.pri 1a
            jzer 10
            jump 11
        l.10
            break
            load.pri 0
            eq.c.pri 1d
            jzer 12
            jump 13
        l.12
        l.13
        l.11
        l.f
        l.d
        l.b
        l.9
        l.7
        l.5
        l.3
        l.1
    Assembly for what people should be doing more often:
    pawn Code:
    break
            load.pri 0
            switch 0
        l.2
            jump 1
        l.3
            jump 1
        l.4
            jump 1
        l.5
            jump 1
        l.6
            jump 1
        l.7
            jump 1
        l.8
            jump 1
        l.9
            jump 1
        l.a
            jump 1
        l.b
            jump 1
        l.c
            jump 1
        l.0
            casetbl
            case a c
            case 2 2
            case 5 3
            case 8 4
            case b 5
            case e 6
            case 11 7
            case 14 8
            case 17 9
            case 1a a
            case 1d b
        l.1
    There is actually a lot more to this, this is just a basic example. Switches with ranges and things are way more optimized than any logic if test. And the timings...
    Quote:

    Timing "if-elseif-else"...
    Mean = 408.00ns
    Mode = 407.00ns
    Median = 407.00ns
    Range = 19.00ns
    Timing "switch"...
    Mean = 100.00ns
    Mode = 97.00ns
    Median = 99.00ns
    Range = 12.00ns

    Yeah, 4 times the speed difference. And again, as I said, this is just a basic example. A more complex example would have an even greater difference.

To be continued...
(so please don't bother replying yet)
Reply


Messages In This Thread
Tiny But Super Optimizations - by Crayder - 28.04.2016, 18:13
Re: Tiny But Super Optimizations - by iGetty - 01.05.2016, 22:18
Re: Tiny But Super Optimizations - by lolumadd_ - 01.05.2016, 22:28
Re: Tiny But Super Optimizations - by Mauzen - 01.05.2016, 22:54
Re: Tiny But Super Optimizations - by AmigaBlizzard - 01.05.2016, 23:20
Re: Tiny But Super Optimizations - by Crayder - 02.05.2016, 02:44
Re: Tiny But Super Optimizations - by PrO.GameR - 02.05.2016, 11:54
Re: Tiny But Super Optimizations - by Vince - 02.05.2016, 12:39
Respuesta: Tiny But Super Optimizations - by aoEXE - 02.05.2016, 13:11
Re: Tiny But Super Optimizations - by Darkwood17 - 02.05.2016, 14:14
Re: Tiny But Super Optimizations - by Crayder - 02.05.2016, 14:26
Re: Tiny But Super Optimizations - by Konstantinos - 02.05.2016, 14:28
Re: Tiny But Super Optimizations - by Yashas - 02.05.2016, 15:27
Re: Tiny But Super Optimizations - by Mauzen - 02.05.2016, 17:52
Re: Tiny But Super Optimizations - by Slice - 02.05.2016, 22:51
Re: Tiny But Super Optimizations - by Macluawn - 03.05.2016, 21:54
Re: Tiny But Super Optimizations - by Crayder - 03.05.2016, 23:04
Re: Tiny But Super Optimizations - by SyS - 04.05.2016, 03:42
Re: Tiny But Super Optimizations - by Crayder - 04.05.2016, 04:24
Re: Tiny But Super Optimizations - by SyS - 04.05.2016, 08:14
Re: Tiny But Super Optimizations - by Marshall32 - 04.05.2016, 08:22
Re: Tiny But Super Optimizations - by Slice - 04.05.2016, 08:29
Re: Tiny But Super Optimizations - by GhostHacker - 04.05.2016, 08:33
Re: Tiny But Super Optimizations - by SyS - 04.05.2016, 08:34
Re: Tiny But Super Optimizations - by Ritzy2K - 04.05.2016, 09:10
Re: Tiny But Super Optimizations - by Wolfe - 04.05.2016, 09:22
Re: Tiny But Super Optimizations - by PrO.GameR - 04.05.2016, 10:23
Re: Tiny But Super Optimizations - by Donboo - 26.08.2016, 09:30
Re: Respuesta: Tiny But Super Optimizations - by PrO.GameR - 27.10.2016, 00:25
Respuesta: Re: Respuesta: Tiny But Super Optimizations - by Swedky - 29.10.2016, 06:05
Re: Respuesta: Re: Respuesta: Tiny But Super Optimizations - by Crayder - 29.10.2016, 17:57
Re: Tiny But Super Optimizations - by NeXoR - 31.10.2016, 03:02
Re: Tiny But Super Optimizations - by Freaksken - 15.11.2016, 13:04
Re: Tiny But Super Optimizations - by Awide - 24.11.2016, 20:16
Re: Tiny But Super Optimizations - by Crayder - 25.11.2016, 03:07
Re: Tiny But Super Optimizations - by Yashas - 25.11.2016, 04:24

Forum Jump:


Users browsing this thread: 2 Guest(s)