Fastest way to check variable against two values

W

wswilson

In python, I could write:

a = 1

if a in [1, 2]:
do something...


In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
do something...
}

Is there a shorter, cleaner syntax?
 
F

fred.l.kleinschmidt

In python, I could write:

a = 1

if a in [1, 2]:
   do something...

In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
   do something...

}

Is there a shorter, cleaner syntax?

It depends on many things, such as what types of variables
you are using (int, double, strings, etc.)

In some cases, using a switch statement is useful here:

switch(a) {
case 1: case2:
/*do something */
break;
case 3: case 4:
/* do something else */
break;
default:
/* etc. */
break;
}


The above is likely to be implemented using a jump table,
which is probably faster than the nested if's. But it
only works if the comparisons are to constants.
 
B

Bartc

wswilson said:
In python, I could write:

a = 1

if a in [1, 2]:
do something...

Is this supposed to be an example of a /fast/ method? I think Python creates
an array containing 1 and 2, then searches it for a.

Being neat and short isn't necessarily fast. However you do it in C, it will
be faster.

-- Bartc
 
E

Eligiusz Narutowicz

Bartc said:
wswilson said:
In python, I could write:

a = 1

if a in [1, 2]:
do something...

Is this supposed to be an example of a /fast/ method? I think Python creates
an array containing 1 and 2, then searches it for a.

Nowhere did he mention "fast". He mentioned shorter cleaner syntax. And
it is.
 
R

Robert Gamble

Bartc said:
wswilson said:
In python, I could write:
a = 1
if a in [1, 2]:
do something...
Is this supposed to be an example of a /fast/ method? I think Python creates
an array containing 1 and 2, then searches it for a.

Nowhere did he mention "fast". He mentioned shorter cleaner syntax. And
it is.

The subject of the message was "Fastest way to check variable against
two values".
 
E

Eligiusz Narutowicz

Robert Gamble said:
Bartc said:
In python, I could write:
if a in [1, 2]:
do something...
Is this supposed to be an example of a /fast/ method? I think Python creates
an array containing 1 and 2, then searches it for a.

Nowhere did he mention "fast". He mentioned shorter cleaner syntax. And
it is.

The subject of the message was "Fastest way to check variable against
two values".

It did indeed . I am sorry - I really only listened to the body of the
message which made it pretty clear. I can think that he is meaning
"fastest to type" in the subject as was clear from the body.
 
W

wswilson

Bartc said:
In python, I could write:
a = 1
if a in [1, 2]:
  do something...
Is this supposed to be an example of a /fast/ method? I think Python creates
an array containing 1 and 2, then searches it for a.
Nowhere did he mention "fast". He mentioned shorter cleaner syntax. And
it is.

The subject of the message was "Fastest way to check variable against
two values".

Thanks for the help guys. I did mention fast in the title but I meant
clean and short (as in the post). Sorry :)
 
R

Robert Gamble

In python, I could write:

a = 1

if a in [1, 2]:
do something...

In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
do something...

}

Is there a shorter, cleaner syntax?

In your example Python creates a list of values and the in operator
compares each element of this list to "a" until it finds such a value
or the list is exhausted. The C method you propose won't likely be
any slower. As far as shorter/cleaner, it depends. There isn't a
better mechanism built into the language but if you are doing
operations like this a lot on multiple values you may want to write a
function to do what the "in" operator does in python, for example:

==cut==
int in_list (int search, int *p, size_t size)
{
for (size_t i = 0; i < size; i++)
if (search == p) return 1;
return 0;
}

int main (void)
{
if (in_list(1, (int []){1, 2, 3, 4, 5}, 5))
puts("element is in list");
else
puts("element is not in list");

return 0;
}
==cut==

In this (C99) example we define a function in_list that takes an
integer to search for, an array of integers to search, and the size of
the array; it returns 1 if the searched for item was found, 0 if it
was not. We call it with a compound literal as a "shorter/cleaner"
method than creating a separate array which you would have to do if
using C89. The two major problems with this function are that it only
works for ints and it is easy to specify an incorrect size with longer
lists. You could generalize the in_list function to work with any
type by modifying it to receive a comparison function and making the
appropriate changes to the types passed on. To alleviate the second
issue you could pass in an array of pointers to values using NULL to
terminate the list, this can get messy for non-string types though. I
have used similar methods successfully in the past, whether it is
"clean" is a matter of opinion.
 
R

Robert Gamble

wswilson said:
In python, I could write:
a = 1
if a in [1, 2]:
do something...
In c (and many other languages):
int a = 1;
if (a == 1 || a == 2) {
do something...
}
Is there a shorter, cleaner syntax?

If none of the values are 0 and none exceed the maximum char:

char ac[] = {1,2};

You are going to need the terminating null character:

char ac[] = {1, 2, 0};
int a = 1;

if (strchar(ac, a)) {

It's strchr, not strchar.
 
B

Bartc

wswilson said:
In python, I could write:

a = 1

if a in [1, 2]:
do something...


In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
do something...
}

If you want something short then, try this macro:

#define in(a,b,c) ((a)==(b) | (a)==(c))

And use it like this:

if (in(a,1,2))...

(Although, I don't use macros much and there are probably some pitfalls. You
may also like to use || instead of |)

-- Bartc
 
P

Peter Nilsson

wswilson said:
In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
do something...
}

Is there a shorter, cleaner syntax?

Shorter, but not necessarily better...

if (a - 1u < 2)
 
U

user923005

In python, I could write:

a = 1

if a in [1, 2]:
   do something...

In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
   do something...

}

Is there a shorter, cleaner syntax?

If the list of items contains a small maximum, you can use:

/*
7.21.5.4 The strpbrk function
Synopsis
1 #include <string.h>
char *strpbrk(const char *s1, const char *s2);
Description
2 The strpbrk function locates the first occurrence in the string
pointed to by s1 of any character from the string pointed to by s2.
Returns
3 The strpbrk function returns a pointer to the character, or a
null pointer if no character from s2 occurs in s1.
*/
#include <string.h>
#include <stdio.h>

/* You can't find zero in the list, and the last entry must be 0: */
static const unsigned char list[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 23, 25, 'a', 'A', 'Z', 'Q', 0
};

int main(void)
{
char string[256];
char *where;

puts("Enter a string:");
fflush(stdout);
fgets(string, sizeof string, stdin);
where = strpbrk(string, list);
if (where)
printf("first match is %d.\n", (int) *where);
else
puts("No characters match.");
return 0;
}
/*
Enter a string:
zzzAn
first match is 65.
*/
 
S

Serve L

wswilson said:
In python, I could write:

a = 1

if a in [1, 2]:
do something...


In c (and many other languages):

int a = 1;

if (a == 1 || a == 2) {
do something...
}

Is there a shorter, cleaner syntax?

Its funny to see what you all come up with while the answer is "no there is
no cleaner way as in python"
 
P

Paul Hsieh

wswilson said:
In python, I could write:
if a in [1, 2]:
do something...

Is this supposed to be an example of a /fast/ method? I think Python creates
an array containing 1 and 2, then searches it for a.

I wouldn't be surprised if this was faster. In Python, or any
interpreted byte-code executed language, reducing the number of byte-
codes is usually more important than the performance of the byte-code
itself. If the vector [1,2] is created at interpretation time (I
don't know if it is or it isn't), then certainly this is probably the
fastest approach in python.
Being neat and short isn't necessarily fast. However you do it in C, it will
be faster.

Indeed. All benchmarks I have seen and written myself put C at
between 50 and 200 times faster than Python on a wide variety of
code. So its always humorous when I hear about things like "Iron
Python" which are supposed to be remarkable for making Python execute
about 3 times faster.
 
B

Bartc

Paul Hsieh said:
wswilson said:
In python, I could write:
if a in [1, 2]:
do something...
Being neat and short isn't necessarily fast. However you do it in C, it
will
be faster.

Indeed. All benchmarks I have seen and written myself put C at
between 50 and 200 times faster than Python on a wide variety of
code. So its always humorous when I hear about things like "Iron
Python" which are supposed to be remarkable for making Python execute
about 3 times faster.

I'd been developing interpreted languages for years to go with my
applications.

For pure integer code, I always found it difficult to break the 10x slower
barrier compared with, say, C (although I'm currently working on that!).

But, I had decided originally that when the interpreted language was used
properly, it should only be between 1x to 2x as slow as a compiled
equivalent, and in most cases this was achieved, while making development a
delight because it was so easy.

Even forgetting library calls, an interpreted language doing high level
things (working with strings, entire arrays, etc) can compare well with pure
C.
 
D

dj3vande

Bartc said:
For pure integer code, I always found it difficult to break the 10x slower
barrier compared with, say, C (although I'm currently working on that!).

But, I had decided originally that when the interpreted language was used
properly, it should only be between 1x to 2x as slow as a compiled
equivalent, and in most cases this was achieved, while making development a
delight because it was so easy.

Even forgetting library calls, an interpreted language doing high level
things (working with strings, entire arrays, etc) can compare well with pure
C.

Interpreted languages doing high level things are most likely
translating one or two language primitives into "call a big chunk of
compiled code", and when you're doing that the return on investment for
spending extra time optimizing the compiled code goes way up, so it
usually ends up faster than writing the code directly in C. (Unless
you do something dumb like using an expensive language primitive to do
an operation that can be done cheaply without it.)
Compiling to native code wins easily when you can't reduce code that
does nontrivial things to a short sequence of language primitives,
though, since the interpreter has to stop and look up what to do again
after every interpreted-language instruction, and compiled code can
skip that part.

I work with people who like to write everything in Matlab.
For what it's good at (pretty much any easy-to-describe numerical
computation), I won't even bother trying to make my C run as fast as
the Matlab runtime. I occasionally convert Matlab code to something we
can call from a C program without having to ship with the Matlab
runtime, but if it's performance-critical I'll tell them to just ship
the Matlab code.
But occasionally they'll come to me with code that loops over a big
array doing something that there aren't Matlab primitives to do
array-at-a-time and that's way too slow, and when that happens I can
easily get a factor of five or ten speedup even before I ask the
compiler to optimize it (i.e. working with one hand tied behind my
back), just by writing C code to do the same thing.
Good interpreted languages[1] make it easy to write compiled-to-native
code and call it from the interpreted scripts, which essentially lets
the user-programmer write their own primitives. Though making it as
easy to optimize as aggressively as they do for the builtin ones is a
little bit harder, and well beyond the scope of what the people who
sell the interpreted languages are trying to do.


dave

[1] Matlab meets this criterion for "good" (it's the only one I've had
reason to find out about).

--
Dave Vandervies dj3vande at eskimo dot com
Have you checked under your desk for stray sixes?
So *that's* where the beast is!
--Normal L. DeForest and Stuart Lamble in the scary devil monastery
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top