c goto动态label跳转
pg表达式引擎里面各个表达式的串联是使用goto动态label实现的。
// 定义部分 #if defined(EEO_USE_COMPUTED_GOTO) static const void *const dispatch_table[] = { &&CASE_EEOP_DONE, &&CASE_EEOP_INNER_FETCHSOME, &&CASE_EEOP_OUTER_FETCHSOME, &&CASE_EEOP_SCAN_FETCHSOME, &&CASE_EEOP_INNER_VAR, &&CASE_EEOP_OUTER_VAR, &&CASE_EEOP_SCAN_VAR, ... // 跳转 EEO_CASE(EEOP_OUTER_FETCHSOME) { CheckOpSlotCompatibility(op, outerslot); slot_getsomeattrs(outerslot, op->d.fetch.last_var); EEO_NEXT(); } // 宏定义 #define EEO_SWITCH() starteval: switch ((ExprEvalOp) op->opcode) #define EEO_CASE(name) case name: #define EEO_DISPATCH() goto starteval #define EEO_OPCODE(opcode) (opcode) #endif /* EEO_USE_COMPUTED_GOTO */ #define EEO_NEXT() \ do { \ op++; \ EEO_DISPATCH(); \ } while (0) #define EEO_JUMP(stepno) \ do { \ op = &state->steps[stepno]; \ EEO_DISPATCH(); \ } while (0)
也就是日常用的比较少的&&操作符。如下:
#include <stdio.h> #include <string.h> enum { ADD, SUB, MUL, DIV, END }; int main(int argc,char *argv[]) { static const void *const disptab[] = { &&L_ADD, &&L_SUB, &&L_MUL, &&L_DIV, &&L_END }; int code[] = {ADD,ADD,MUL,MUL,END}; int i = 0; int sum = 0; goto *disptab[code[i++]]; L_ADD: sum += 2; goto *disptab[code[i++]]; L_SUB: sum -= 2; goto *disptab[code[i++]]; L_MUL: sum *= 2; goto *disptab[code[i++]]; L_DIV: sum /= 2; goto *disptab[code[i++]]; L_END: printf("sum = %d\n",sum); return 0; }
其等价于switch case,如下:
for() { switch() { case ADD: sum += 2; break; case SUB: sum -= 2; break; case MUL: sum *= 2; break; case DIV: sum /= 2; break; case END: } }
相比来看,速度会更快。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-10-06 java性能优化之HashMap,LinkedHashMap,TreeMap读取大量数据效率的比较