Comments 6
Этот код использует ячейку памяти размера 8 бит (char*
) вместо 16-битной (size_t
), и на 1-3 инструкции меньше (поправьте, я не особо понимаю ассемблер).
char* это указатель и он не равен 8 бит.
про ассемблер - сравнить можно тут на разных компиляторах:
Да, и, например, clang-15 генерирует абсолютно идентичный код для обоих вариантов с оптимизациями O2. А вот GCC-13 при О2 вариант с индексом вообще распознает как strlen, и просто вызывает ее.
Так что пример для иллюстрации идеи про "микрооптимизации"/"микропессимизации" очень плохо выбран. Ведь, как известно, поиск длины строки в С -- это O(n). Более разумной оптимизацией в случае, когда считать длину строк надо часто, было бы сделать толстую обертку над char *, в которой бы хранилась длина, посчитанная один раз. Ну или хотя бы использовать стандартную библиотечную strlen, а не самописную -- strlen из glibc обрабатывает по 4 байта за раз.
Если вы откроете асм с -03, то скорее всего окажется что компилятор заменил ваш strlen на векторизованный вариант, оптимальный для данного CPU. Не стоит считать себя умнее компилятора, а ещё лучше использовать пикс для поиска таких мест, оптимизация "глазами" лет 20 как малоэффективна
Этот код использует ячейку памяти размера 8 бит (char*) вместо 16-битной (size_t)
Оптимизация здесь заключается совсем не в изменении размера ячейки памяти, а в удалении индексной переменной. Этим получают сразу несколько выгод:
- Вдвое уменьшается количество регистров процессора, задействованных для хранения локальных переменных. Это в конечном итоге означает меньшее количество обращений к медленной памяти.
- Вместо индексной адресации используется косвенная, что для некоторых процессоров означает меньшее число ассемблерных команд и задействованных регистров, а для других — меньшее число задействованных блоков процессора, освобождение которых позволяет выполнять несколько команд одновременно
Микро оптимизация и где её нужно применять