Skip to content

Instantly share code, notes, and snippets.

@eZanmoto
Created February 1, 2012 12:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eZanmoto/1716744 to your computer and use it in GitHub Desktop.
Save eZanmoto/1716744 to your computer and use it in GitHub Desktop.
find
int find ( int target, const int *array, const size_t size ) {
int index = 0;
while ( index < size && array[ index ] != target )
index++;
return index < size ? index : -1;
}
@eZanmoto
Copy link
Author

eZanmoto commented Feb 1, 2012

The last line isn't very readable, but this can be abstracted into an intention-revealing function, say, get_in_range( i, min, max ), which returns i if the variable is in range, and -1 otherwise. The benefit of the one-liner is that it takes constant time. Is it really better though?

A pretend disassembly of return ( index % size ) + ( index / size * -1 );

MOV    A, [ ADDRESS OF INDEX ]
MOV    B, [ ADDRESS OF SIZE ]
DIV    A, B ; A CONTAINS A / B, D CONTAINS A % B
PUSH   D
; DEPENDING ON THE COMPILER OPTIMISATION, IT MAY NOT REALISE THAT A / B WAS ALREADY COMPUTED
MOV    A, [ ADDRESS OF INDEX ]
MOV    B, [ ADDRESS OF SIZE ]
DIV    A, B ; A CONTAINS A / B, D CONTAINS A % B
IMUL   A, -1
POP    B
ADD    A, B
PUSH   A
RET

So this weighs in at 12 instructions (I'm not going to compute sizes). So a more descriptive version of the last line would be

return index < size ? index : -1;

which I'll pretend to disassemble again

    MOV    A, [ ADDRESS OF INDEX ]
    MOV    B, [ ADDRESS OF SIZE ]
    TEST   A, B
    JGE    _ELSE
    PUSH   A
    JMP    _ENDIF
_ELSE:
    MOV    A, -1
    PUSH   A
_ENDIF:
    RET

So this weighs in at only 9 instructions, and is much more clear, so I'm going to change this gist :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment