Стили программирования C и C++ и производительность

В большинстве случаев различия в производительности, связанные со стилем программирования на С или С++, неочевидны, а иногда их вообще можно определить только экспериментально.

Ниже приведены некоторые рекомендации:

  • Везде, где только возможно, используйте тип int вместо char или short.

    В большинстве случаев для обработки типов char и short требуется выполнить больше команд. Выполнение дополнительных команд занимает время, а кроме того, эти команды займут в исполняемом коде больше места, чем будет сэкономлено за счет применения более коротких чисел (если речь не идет о больших массивах данных).

  • Если же необходимо использовать тип char, то везде, где это возможно, указывайте unsigned char.

    Для загрузки данных типа signed char в регистр требуется выполнить на две команды больше, чем для данных типа unsigned char.

  • Везде, где это возможно, заменяйте глобальные переменные локальными.

    Для обращения к глобальным переменным требуется выполнить больше команд, чем для обращения к локальным переменным. Кроме того, если явно не указано иное, компилятор предполагает, что вызванная подпрограмма может изменять значения всех глобальных переменных. Таким образом, после вызова подпрограммы значения всех глобальных переменных загружаются в память повторно, что приводит к снижению производительности.

  • Если необходимо обратиться к глобальной переменной (которая не является общей переменной для этой и других нитей), скопируйте ее значение в локальную переменную и работайте с копией.

    Использование локальной копии дает выигрыш в производительности, за исключением случая, когда обращение к глобальной переменной осуществляется только один раз.

  • При записи результатов, а также при сравнении лучше применять двоичные коды, а не строки. При работе со строками увеличивается как количество команд, так и объем памяти, необходимый для хранения данных. Например, последовательность операторов
    #define situation_1 1
    #define situation_2 2
    #define situation_3 3
    int situation_val;
    
    situation_val = situation_2;
    . . .
    if (situation_val == situation_1)
    . . .

    выполняется намного быстрее, чем последовательность

    char situation_val[20];
    
    strcpy(situation_val,"situation_2");
    . . .
    if ((strcmp(situation_val,"situation_1"))==0)
    . . .
  • Если необходимо использовать строки, то везде, где это возможно, применяйте строки фиксированной длины, а не строки переменной длины, оканчивающиеся символом NULL.

    Процедуры семейства mem*() (такие как memcpy()) выполняются быстрее соответствующих процедур семейства str*() (например, strcpy()). Это связано с тем, что в процедурах семейства str*() каждый символ сравнивается с символом конца строки, в то время как в процедурах mem*() этого не делается.