Банановые шкурки
Некоторые порочные техники программирования похожи на банановые шкурки. Все знают, что можно поскользнуться. Вид человека, поскользнувшегося на банановой шкурке, завсегда вызывает веселье. Всегда находятся знатоки, которые уверждают, что пройтись по банановой шкурке и не поскользнуться – это в сущности очень просто. Не верьте таким, ибо есть они волки в овечьих шкурах.
Сижу я, смотрю на код “сетевого движка”. Там обертка над сокетами, которая есть суть std::vector<byte>. С одной стороны мы асинхронно добавляем сообщения ( которые тоже суть std::vector<byte> ), к другой стороне этого вектора присосался сокет, который не менее асинхронно выбирает сообщения и посылает по 256 байт на удаленный сервер. Пошел ругаться с серверными программистами.
Стал говорить, что stl в низком уровне омерзительна, как размокший окурок в писсуаре. Что-де мне не известно позитивных случаев применения стандартной библиотеки в низком уровне.
Моя эскапада была прервана в том духе, что-де “у тебя самого в рендере push_back в std::vector без предварительного резервирования”. Я был вынужден свои излияния по поводу отстойности stl прекратить, ибо таки-да. Есть такое у меня в рендере. Пробормотал я что-то по поводу “драфтовости” кода и удалился.
Стал пристально вглядываться в свой замечательный код рендера. Там действительно используются std::vector’а. В двух местах. В первом месте я собираю запросы на occlusion cull. Собираю окклюдеры и ресиверы в очередь, сортирую, потом собственно считаю видимость.
И аналогичный фрагмент, где итерируюсь по рендер-объектам, каждый рендер-объект выбрасывает набор рендер-примитивов. Потом я сортирую их и выполняю. Сортирую по приоритету, а полупрозрачную сцену по удалению.
Промежуточным контейнером рендер-примитивов выступает std::vector. Добавление производится с помощью push_back. А сортировка в обоих случаях производится по целому числу, вполне хватает шестнадцати бит.
Реализация STL у нас своя, местами забавная. Смотрю в код, вижу что sort делает внутри new и выполняет сортировку слиянием.
Убиваю эту дурацкую сортировку с аллокацией, делаю такую же, как и в партиклах. Корзиночную, два прохода по 256 корзинок. Убиваю std::vector, вставляю фиксированный массив на 16 тысяч рендер-примитивов.
Перекомпилирую… Удивленно вижу, что fps поднялся ровно в полтора раза в debug версии. Ценой сотни что ли строк кода. В release не так значительно, но все одно – сильно быстрее. В самой обычной игре скорость в полтора раза поднялась, не в синтетических тестах.
Не верьте людям, которые уверяют, что умеют ходить по банановой кожуре в промышленных масштабах. И сами не пытайтесь.