Использование указателей goto, вероятно, приведет к более медленному коду, потому что он отключит некоторые другие оптимизации gcc (или будет в последний раз, когда я читал об этом).Gcc по существу решает, что это может быть слишком сложно, чтобы не отставать от того, что может происходить, и предполагает, что гораздо больше инструкций перехода может быть нацелено на каждую метку goto, которая была &&, чем на самом деле.Если вы настаиваете на попытке использовать этот метод, я предлагаю вам попытаться использовать целое число и другой переключатель / регистр, а не goto.Gcc захочет разобраться в этом.
Кроме того, для многих утверждений это может не стоить работы, или она может действительно работать лучше, чем она есть.Это действительно во многом зависит от того, что на самом деле stmt
.
Рефакторинг stmt
в static
функцию, вероятно, даст хорошие результаты, если stmt
действительно дорогой или большой код.
Еще одна вещь, которую вы могли бы попробовать, если бы вы могли вывести stmt
из переключателя / корпуса и просто выполнить, всегда выполнять ее.Иногда это самый дешевый способ, но это действительно зависит от того, что на самом деле делает * 1012.
Еще одна вещь, которую вы можете сделать, это рефакторинг всех stmt
, do_stmt_related2A
и do_stmt_related2A
всехв файл static
функций, например:
// args in this is just a psudocode place holder for whatever arguments are needed, and
// not valide C code.
static void stmt_f(void (*continuation)(arg_list), args) {
stmt; // This corresponds almost exactly to stmt in your code
continuation(args);
}
static void do_stmt_related2A_f(args) {
do_stmt_related2A;
}
static void do_stmp_related2B_f(args) {
do_stmt_related2B;
}
...
switch (condition) {
case A:
stmt_f(do_stmt_related2A_f, args);
break;
case B:
...
Вызов функции продолжения в конце stmt_f является хвостовым вызовом и, скорее всего, станет прыжком, а не реальным вызовом.Поскольку все они статичны, возможно, что компилятор увидит весь набор значений, которые могут быть функциями продолжения, и оптимизирует их еще немного, но я не знаю этого.
Если stmt не очень большой, этоочень вероятно, что это микрооптимизация, которая просто не стоит этого.Если вы действительно хотите знать, то вы должны скомпилировать сборку и попытаться увидеть, что компилятор действительно делает с вашим исходным кодом.Он вполне может справиться с этой задачей лучше, чем вы думаете.
О, последнее, что вы можете попробовать, если вы контролируете, какие фактические значения A, B, C ... могут принять, тогда вы можете убедиться, чтоу тех с подобными префиксами есть смежные значения.Если A и B действительно находятся рядом друг с другом и если компилятор решит, что ему нужно разбить переключатель / регистр на несколько разных таблиц переходов, то он, скорее всего, поместит A и B в одну таблицу переходов и также увидит, что они имеюттот же префикс и поднять этот код для вас.Это более вероятно, если C, который не разделяет этот префикс, не смежен с A или B, но тогда ваш общий код может быть хуже.