这太酷了。我非常明白你的意思。我最近才经历过。
检查完成后 if 将无用,您切换到另一个分支,它将继续运行。
例如这里有一个例子来解释这个问题。想象一下,我们有一个方法或回调,只需要在第一次运行某些东西。或者经过一些迭代。一旦切换,它将仅在 else 或第二个代码上继续运行。
所以有一个无用的 if 是一个无用的开销。如果能完全切换方法就好了。
这里是如何在 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);
这是一个真实的例子:
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);
}
}
还有一个例子:
这只有第一次调用需要检查。它不会适用于所有其他人。
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
}
);
和第一次版本方法
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
我想现在这个想法已经很清楚了。
这里是如何在 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)
这里是运行结果:
CPU、编译器和分支
最后,我们需要引入分支预测器及其工作原理。以及为什么分支可能不好。以及为什么预测器可以做伟大的事情。最近的 cpu 做得很好。
关于这个主题的链接不要太长
https://stackoverflow.com/a/11227902/5581565
What do compilers do with compile-time branching?
https://stackoverflow.com/a/32581909/7668448
为了不让列表更长,我会停止。
当涉及到在多次调用的回调或循环中使用 if else 时。如果在一段时间后它只在一个分支上继续执行。我认为使用运行统计信息的分支预测器将为继续运行的分支进行优化。那么它可能根本不重要。我将进一步调查此事并做一些基准测试,然后我会更新答案。但这一点是需要注意或考虑的。
我希望这会有所帮助。编码愉快。