Today we are going to tackle a trivial problem of counting the number of odd numbers in the [0..n) range in Python. Probably the most straightforward way to accomplish this is
Apart from being overly procedural and non-idiomatic, it looks reasonable and performs well enough
if statements in loops always bother me and in such cases in C++ I usually end up implicitly converting boolean to int. Let’s try doing something similar in Python
Great, no if! Just in case let’s see how it performs
Ouch, looks like it’s almost 70% slower :( What’s going on? Well, the answer can be found in its bytecode. The version that’s using if statement using jumps
but the “casting” version is using a function call under the hood:
and as we’ve already established, Python function calls are very expensive. We can easily verify this by getting rid of the explicit int call and rely on implicit conversion
Its bytecode no longer contains any function calls
and is outperforms our conditional version
Obviously, in this particular case, the equality check is not really necessary since we can just add the remainder to total
and get even better numbers
but the moral of the story is that things like int are not casts but full-blown function calls and as such should not be applied similar to C/C++ casts.
Bonus. Just for fun I’ve also added a few more implementations that are somewhat more idiomatic in Python
and while using_sum_generator was pretty close to our fastest procedural implementation
the version using reduce was slower despite not having equality check
bummer that the reduce() was not as good :(