标签作为值与switch语句

A.M*_*M.M 4 c gcc

我最近读到有关标签的价值,

int main(){
    int value  = 2;
    const void *labels[] = {&&val_0, &&val_1, &&val_2};
    goto *labels[value];
    val_0:
        printf("The value is 0\n");
        goto end;
    val_1:
        printf("The value is 1\n");
        goto end;
    val_2:
        printf("The value is 2\n");
        goto end;
    end:
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

我要问的是,使用此方法而不是使用switch语句或指针数组是否真的有任何性能提升?

CB *_*ley 5

这是一个非标准的扩展,在这种情况下可能不会比等效的switch语句更好,并且应该避免恕我直言.switch语句更清晰,更易于维护.

(我快速测试了我的gcc版本,它为这段代码和一个等效的switch语句生成了完全相同的代码.但它不是代表性的测试,因为它优化了所有内容,除了实际选择的代码路径.)

一个潜在的性能考虑因素是switch语句必须具有合理的行为,即使value它不在正确的范围内,您的版本具有未定义的行为,因此编译器可能能够避免某些代码中的范围检查.

  • 这被称为直接线程,并且与在非常敏感的性能部分中使用交换机相比具有明显的优势,因为仅产生单个分支误预测.你是对的,它不应该被用作switch语句的常见替代品,其中性能不是问题. (6认同)
  • 同意@MartinKällman.例如:Erlang/OTP有一个特殊的文件`beam_emu.c`,在编译时没有使用label-as-value gcc扩展名,使整个Erlang的速度降低30-40%. (2认同)

ale*_*oot 3

我认为 switch 语句更具可读性和更简洁,因此使用它而不是数组,除非问题不太适合 switch 语句。

标签作为值的最佳用途是在线程代码的解释器中:

解释器函数中的标签可以存储在线程代码中,以实现超快速调度。