+79 голосов |
1. Всем программистам рекомендую настоятельно маленький (меньше 100 KB) pdf-файлик - Феликс фон Лейтнер, "Оптимизация [на уровне] исходных кодов".
Фактически это сборник примеров реакций нескольких самых ходовых компиляторов (свежих) на разные фрагменты кода и приёмы, часто испольуземые программистами. Компиляторы - GCC 4.3, Sun C 5.9, Intel C и MSVC 2008.
В целом получается очевидное - элита программирования (разработчики компиляторов) потому и элита, что много грамотнее многих обычных программистов-прикладников. Ну а задачи оптимизации исходного кода, похоже, сейчас ограничиваются умелым и эффективным использованием иерархии памяти - разные трюки и традиционные приёмы дают несоизмеримо меньший эффект. Например, замена умножения операцией сдвига позволяет выиграть всего несколько машинных тактов, а вот неверно выбранные структуры данных и объем данных обеспечивают проигрыш 250 тактов при каждом обращении к непопавшим в кэш-память данным.
Выводы самого фон Лейтнера лаконичны:
- если вы оптимизируете код, тестируйте его производительность на реальных данных;
- если выигрыш от оптимизации не очень велик, а оптимизация привела к увеличению сложности и снижению понятности кода, откажитесь от оптимизации.
2. Отыскался ещё изящный прием (точнее даже идиома) комментирования кода, правда, головоломный и небезопасный в том смысле, что визуально плохо воспринимается. В общем, - одним символом включать-выключать кусок исходного текста можно так:
фрагмент выключен из кода
/*
фрагмент_A
// */
фрагмент включен, если в начало первой строки добавить один символ "/"
//*
фрагмент_A
// */
Можно обойтись без стилевой смеси С/C++ комментариев (хоть она и разрешена новыми стандартами C), и получить даже более читабельный код:
фрагмент выключен из исходного текста:
/* /
фрагмент_A
/**/
фрагмент включен в исходный текст:
/**/
фрагмент_A
/**/
3. Опасности трамбовки типов (type punning).
Ready, set, buy! Посібник для початківців - як придбати Copilot для Microsoft 365
+79 голосов |
Большое спасибо за ссылку! Очень интересно! Впринципе в теории всё понятно, а вот наглядных примеров часто не хватает. Кстати, насчет операций, большинство арифметических операций довольно хорошо выполняются современными процессорами, потому и прирост быстродействия невелик. Другое дело если вы работаете с операциями посложнее, скажем умножение больших матриц или вычисление корня квадратного (кстати это встроенная операция на SPARC насколько я знаю), короче говоря, что-то сложное. Тут каждые пару тактов буду играть роль и возможно имеет смысл написать какие-то оптимизированные версии умножения и т.д. Да и как показывают тесты компиляторы для С не то что вы 80-х годах, стали поумнее, оптимизируют код очень хорошо. Особенно gcc.
Для повседневого прикладного программирования самая дорогая операция - memory access. Особенно если данные не находятся в кэше. Так что оптимизация памяти в большиснтве случаев даёт бОльший прирост производительности чем оптимизация арифметических операций.