Про строки

В процессе портирования одной игры на Sony PSP возникла “классическая” проблема с нехваткой памяти. Впихнуть в N/10 мегабайт памяти игрушку – ещё то развлечение.

Игра была написана, можно сказать по книжке про C++ и STL, но, к счастью, без книжки Александреску. Код довольно чистый и аккуратный, но, поскольку товарищи считают, что памяти много, то аллокации считать не надо, и можно смело делать, например, new ButtonPressedEvent() внутри кадра (это обеспечило дикое, по моему мнению, количество выделений памяти).

Здесь я расскажу ещё и о том, что в проекте всюду использовался std::string (и wstring) (на самом деле был самодельный клон, который по своей сути работал точно также, но позволял делать гадкую вещь – присваивать юникодным контейнерам неюникодные строки и наоборот, в остальном – тоже самое).

При старте игры зачитываются xml конфиги, из которых вычитываются пути к почти всем ресурсам и загружаются сразу в память. После этого вступительные ролики и главное меню.

В общем в результате при входе в главное меню у нас наблюдалась картина:

nAllocatedBlocks 47089
nAllocatedSize 14563733
peakAllocationSize 17645007

Как мы видим – 47 тыс аллокаций, дающих в результате 14,5 МБ.

Решено было перевести такую безобидную вещь, как Filename (т.е. имя файла с ресурсами, которые загружаются и по которым потом работают ещё всякие мапы и прочие поиски – тоже зло, конечно) с std::wstring (а иногда std::string) на фиксированую строку rk::String<1024> (в зависимости от настроек компилятора она внутри или char, или wchar_t, в нашем случае wchar_t).

Возни при переделке было очень много. Из злобных вещей, которые сразу всплывали – были “неявные” конверсии между ANSI – Unicode – т.е. выражение вида std::wstring filename = “texture.png” на самом деле вызывало бурю эмоций у системы, т.к. нужно было сначала создать строку ansi, создать буфер в памяти, сконвертить её в юникод и потом записать в целевой контейнер. И это только потому что автор забыл написать перед строчкой букву L (L”text”). Ну а поскольку встречались эпические куски кода, где разные строки конкатенировались  из фрагментов, где часть была анси, а часть юникод, чтобы получить полный путь к ресурсу – то получаемый оверхед представляется значительным.

После того, как весь код, связанный с именами файлов был переведён на фиксированые строки и использование только юникодных строк у нас получилась следующая картинка в главном меню:

nAllocatedBlocks 16978
nAllocatedSize 10259790
peakAllocationSize 12734865

Как мы видим – количество произведённых аллокаций уменьшилось почти в 3 раза, это в основном заслуга того, что исчезли неявные конверсии кодировок.

А вот выигрыш по памяти – почти 5МБ (30%) – это уже серьёзная заявка на успех, при том, что rk::String<1024> явный оверкилл и перерасход для имён файлов, длина которых врядле превысит 128 символов (хотя скорее всего здесь была или жуткая ошибка в логике игры, и строки плодились, как кролики, или странная странность в измерениях, но это поведение я буду и дальше изучать, вместе с дальнейшим выпиливанием динамических строк).

Собсно что я хотел рассказать в этом посте:

Старайтесь использовать фиксированые строки. Как правило, в игровом коде нету необходимости динамически менять строки и делать с ними всякие гадкие вещи. Если же вы видите, что ну никак без этого не обойтись – то это скорее всего из-за того, что, либо у вас очень высокая квалификация и вы точно знаете, что делаете и как оно будет работать, либо у вас наоборот – не очень высокая квалификация – и тогда стоит подумать ещё над проектом – может всё-таки найдётся возможность обойтись?

Не смешивайте в рамках одного проекта разные кодировки, особенно с неявными преобразованиями (их вообще лучше запретить под страхом луча поноса в сторону автора). Изначально определитесь, ANSI, UTF-8, UTF-16 или ещё что-то и пользуйтесь чем-то одним. Идеально – все статические строки оборачивать макросом типа _T(), который на основании настроек компиляции будет выбирать кодировку. Этим вы облегчите жизнь не только себе, когда внезапно окажется, что нужно делать японскую локализацию, но и тем людям, которые в будущем будут поддерживать ваш код. Ну и избежите ненужного оверхеда 🙂

Similar Posts

  • VS2005 Automation

    Я пишу Add-in для студии, который бы позволил более эффективно компилировать проекты gcc компилятором, которым мы пользуемся. На данный момент самой важной и насущной проблемой является управление компилятором, получение текущих настроек и установка своих, и вот тут начинаются проблемы 🙁 Для любого Add-in доступен объект типа EnvDTE2, который предоставляет доступ ко всему, что есть в…

  • погодка

    Что может быть лучше, чем дождь и +4 зимой? Только дождь и -4 зимой! Отковырять лёд со стёкол на машине становится нетривиальной задачей, дойти до этой самой машины тоже 🙂 Вчера на полном приводе было хорошо по этому щастью рассекать, сегодня на переднем с летней резиной было стрёмно 🙂 Share this post: Share on X…

  • Vi iMproved

    Напишу-ка я про один из самых интересных текстовых редакторов. Идея появилась после того, как я нашел аддин – интегрирующий основную функциональность в студию. http://viemu.com/ В связи с моим администраторским увлечением (я занимаюсь небольшим саппортом нескольких серверов фирмы моих знакомых) мне пришлось познакомиться с консолью юникса, а там и с текстовыми редакторами – конфиги-то надо править…

  • Последняя доводка перед новым техно-релизом

    До нового релиза осталось немного 🙂 Наконец закончил человеческую камеру, осталось пофиксить пару надоедливых багов и наконец залить воду – и можно будет релизить. Share this post: Share on X (Twitter) Share on Facebook Share on LinkedIn Share on Email Share on Reddit

  • КРИ 2K7

    Что-то смотрю модно стало писать отчёты про КРИ, напишу-ка и я один 🙂 6.04.07 Приехали в мск и поехали к ddima, который согласился меня с stalker_taurus принять у себя. Забросили весчи и поехали все вместе на конференцию. Первый день был каким-то не очень внятным, лекций почти не было, а то, что было – как-то не…

  • Ездил на выходные в Москву к и на днюху к . Уфблин – столько приключений за один день – это капец 🙂 Подробностей разглашать не буду, но мне до сих пор это аукается – спать хоцца, а вива всё ещё нет на работе, и похоже, может и завтра не будет… Share this post: Share on…