Если вы собираетесь проверять эти вещи только в одном центральном месте, я рекомендую использовать switch
, если возможно, и if/else
, если нет.
Для начала на самом деле проще расширять и добавлять новые случаи, если они вам нужны, чем писать новую функцию, проверять что-то и использовать указатель на функцию. Решение с указателем на функцию становится проще расширять, если у вас возникнет соблазн проверить условия в нескольких местах.
Но, во-вторых (что менее важно), он будет иметь тенденцию быть более эффективным, иногда значительно, и способами, которые выходят за рамки простого сравнения стоимости динамической отправки и локального перехода/перехода. Это потому, что вы даете оптимизатору гораздо больше информации для работы.
Однажды я обнаружил случай, когда GCC 5.3 удалось сжать сложный набор switch cases
, включающий несколько вызовов функций в каждом случае, в единую справочную таблицу без ответвлений, какие данные загружать в регистры. Я ожидал увидеть таблицу переходов, но она пропустила всю таблицу переходов и просто выяснила, какие данные нужно загрузить для каждого случая без ветвления вообще.
Я был настолько впечатлен, что даже не осознавал, что через все эти cases
вызывающие функции все может сводиться к загрузке данных из LUT. Но я почти уверен, что он не смог бы раздавить мой код, если бы были задействованы косвенные вызовы функций. В конечном итоге они служат барьерами оптимизации, если только оптимизатор не настолько умен, что может генерировать все пути кода для каждого возможного типа указателя функции, который может быть вызван, выясняя, какие функции будут вызываться через данный FP.
person
Community
schedule
21.12.2017