That's too cool. I understand very well what you mean. I just went through that lately.
The if will be useless after the check is done and you switch to the other branch, that it will keep running.
For instance here an example to explain the problem. Imaging we have a method or callback that need to run something only the first time. Or after some number of iteration. Once it's switch it will keep running only on the else or the second code.
So having a useless if is a useless overhead. If we can switch completely the method it will be nice.
Here how it can be done in JavaScript
const execCallback = version1WithCheck;
function version1WithCheck() {
if (myCondition) {
// do something
} else {
execCallback = version2NoCheck; //<----- changing the ref of your execCallback variable (which need to be global (in js it will be a closure))
execCallback();
}
}
function version2NoCheck() {
}
function someEventListener() {
execCallback();
};
event.listen(someEventListener);
Here a real example:
private _tradesInsertToDbWithCheck(trades: Trade[]) {
if (!this._checkIfTradesNeedToBeInserted(trades)) {
const sortedTradesToBeInserted = trades.filter((trade: Trade) => {
const firstTradeInfo = this._firstTradeMapping[
objectToExchangeSymbolSignature<Trade>(trade)
];
return trade.id >= firstTradeInfo.id;
});
this._insertTradesIntoDb(sortedTradesToBeInserted);
} else {
//-------- here i switch -----
// ||
// \/
this._insertToDbOnProcessCallback = this._tradesInsertToDbWithoutCheck;
this._insertToDbOnProcessCallback(trades);
}
}
And another example:
This one only the first call will need to check. And it will not for all the rest one.
exchangeClient.onTradeFeedCallback = this._onFirstFeedTrade as OnTradeFeedCallback;
//---------------------^^ we set our ref callback (to first time only version)
exchangeClient.streams[symbol as string_symbol] =
exchangeClient.client.ws.trades(
symbol,
(trade) => { //<------------ here the callback
(exchangeClient.onTradeFeedCallback as OnTradeFeedCallback)(trade as Trade, workers, exchangeClient);
//----------------------------^^^^ here calling our refCallback
}
);
and on first time version method
private _onFirstFeedTrade(trade: Trade, workers: Worker[], exchangeClient: ExchangeClientObject) {
/**
* this run only once
*/
//_______________alter callback function (this no more will be called)
exchangeClient.onTradeFeedCallback = this._onTradeFeed;
// do some things
// next time this._onTradeFeed will be called
I think by now the idea is clear.
And here how it can be done in python
callback = None
def version1(index):
global callback
print('im version 1')
if index == 5:
callback = version2 // <---- switch upon that condition
def version2(index):
global callback
print('im vesrion 2')
callback = version1
for i in range(0,20):
callback(i)
And here the running result:

Cpu, compilers and Branching
And to finish we need to bring in the branch predictor and how it works. And why branch can be bad. And why the predictor can do great things. And recent cpu do great job.
To not go long on that here links about the subject
https://stackoverflow.com/a/11227902/5581565
What do compilers do with compile-time branching?
https://stackoverflow.com/a/32581909/7668448
To not make the list even longer i will stop at that.
And when it come to using the if else within a callback that get called many many times or a loop. If after a certain time it only keep executing on one branch. I think that the branch predictor using the run statistics will optimize for the branch that is keeping running. Then it may just not matter at all this way. I will investigate the matter even farther and do some benchmarks and then i will update the answer. But that point is something to be aware of or consider.
I hope this was helpful. Happy coding.