My Thoughts A blog of all time

Runtimes 2

Verbose if else v.s. one-liner if else

This is a case that I believe to have seen actually impact runtimes somewhat consistently, so I’m interested to see if it was placebo or if this small change actually affects the runtime. The example goes as follows:

Case 1: Verbose

def ifelse(x):
	if x:
		return True
	else:
		return False

Case 2: One-liner

def ifelse(x):
	return True if x else False

We can see that given the same input x, we would get the same result in the return statement. In my experience, I believe that the one-liner implementation is faster.

Now to see what differs in the bytecode:

Case 1:

 2 LOAD_FAST                0 (x)
 4 POP_JUMP_IF_FALSE        1 (to 8) 

 6 RETURN_CONST             1 (True)

 8 RETURN_CONST             2 (False)

Case 2:

 2 LOAD_FAST                0 (x)
 4 POP_JUMP_IF_FALSE        2 (to 10)
 6 LOAD_CONST               1 (True)
 8 RETURN_VALUE
10 LOAD_CONST               2 (False)
12 RETURN_VALUE

At a first glance, this doesn’t really look good for one-liner implementation. It’s two lines longer where it requires the virtual machine to load the Boolean values in the instruction LOAD_CONST and then returning the value instead of the combined instruction RETURN_CONST. Running timeit once again provided not very helpful results. There was no particular trend when testing the functions using both True and False as parameters.

In the process of looking for why this discrepancy occurs, I found the Github issue that originally proposed the creation of the RETURN_CONST instruction. Surprisingly this issue was opened fairly recently, February 7th, 2023, only about a year ago. The original author proposed a change to combine instances of LOAD_CONST and RETURN_VALUE as they appeared in pairs very often. Their notes say that adding the combined instruction created a small performance boost.

What really surprised me here was how little discussion was needed to push this change. While the author did provide a lot of evidence towards the performance gain and the frequency of occurrences, it is still interesting that there was no debate at all in adding this feature.

Which lead me to this issue. It was opened a mere month after the addition of RETURN_CONST and brings up some points as to why RETURN_CONST should be removed. This issue was not raised in the original CPython repo but in a branched project called faster-cpython which was started as a Microsoft backed project to make Python faster. I’m getting off topic now but there are some interesting points raised in that thread that could belong in the original issue. A change like introducing a new instruction seems like a big enough change that it warrants a larger discussion, but perhaps allowing more or less non-intrusive changes like this makes the CPython project more attractive for developers to contribute their time to.

Wow, that went way off topic. Based off of the raw instruction count and the existence of the RETURN_CONST instruction, these elements imply that the verbose method should be the faster of the two.

It might be worth looking into why the one-liner doesn’t combine the LOAD_CONST and RETURN_VALUE instructions into one RETURN_CONST.


Footnote: I found an even earlier mailing list entry discussing the idea of introducing RETURN_CONST back from 2017. They propose the exact same idea but they say that they didn’t have enough bandwidth to drive the idea at the time.