Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate parameter for 0 or 1

Tags:

c

I have a parameter num of int type, where the user can give it one of two values: 0 or 1.
I can check it using the obvious:

if (num < 0 || num > 1)
    print("The parameter value is incorrect.\n");

But I was wondering if there was a better (faster? less code?) to do this?

EDIT
This is some data flow code, so performance is of the essence. I am looking for a faster way to run this check.

Thanks

like image 719
shapiro yaacov Avatar asked Sep 02 '26 04:09

shapiro yaacov


2 Answers

I'd go on clearness instead of less characters:

if (num != 0 && num != 1){
    print("The parameter value is incorrect.\n");
}

when it's 2 AM and you're debugging a program, the last thing you want is to over-think about ranges and bitwise operations.

like image 167
David Haim Avatar answered Sep 03 '26 17:09

David Haim


Clear code over (naive) micro-optimizations

You are essentially making wrong assumptions about actual compiler's behavior. In both cases, that is:

if (num < 0 || num > 1) { ...

and

if (num != 0 && num != 1) { ...

an optimizing compiler will reduce it anyway into shortest form. You may see that, both generate the same assembly, that might look as (x86 platform):

cmp    $0x1,%eax
jbe    1e <foo+0x1e> # jump if below or equal

This is already fast enough, as cmp instruction on all major architectures has latency of one cycle.

The bottom line is to choose whatever code, that makes your intent clear for you, future maintainers and let the compiler do its job. Just make sure, that you set it with proper optimization level (e.g. -O2 or better).


Aid branch prediction

However, if performance is really crucial here (and you profiled it as so, don't you?), then you could think about another kind of optimization, that is at branch prediction level (assuming that your CPU has support for it). The GCC has __builtin_expect intrinsic, that allows to hint compiler, that in most cases branch will be taken or not.

You may use __builtin_expect to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (-fprofile-arcs), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.

For instance, if you are confident, that function takes 0 or 1 in aproximately 99% number of cases, then you could write it as:

#define unlikely(x) __builtin_expect((x), 0)

if (unlikely(num != 0 && num != 1)) { ...
like image 27
Grzegorz Szpetkowski Avatar answered Sep 03 '26 17:09

Grzegorz Szpetkowski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!