дублер каскадера АЛЕКСАНДР ГЛАДЫШ Спецвыпуск: Хакер, номер #071, стр. 071-068-8 Тем не менее, может возникнуть необходимость оптимизации процесса загрузки данных и создания из них «живых» объектов логики приложения. Наиболее эффективный способ сделать это – убрать всякую загрузку данных и оставить только код создания и настройки объектов с зашитыми намертво параметрами, узкоспециализированный под конкретный рассматриваемый случай и набор данных. Уничтожить всю архитектурную прослойку в коде и оставить только нужную в данный момент функциональность. Существует способ добиться такого эффекта автоматически и относительно бесплатно на основе имеющихся данных в описываемом формате. Впрочем, такой способ эффективен только в том случае, когда данные статичны относительно основного приложения, то есть число загрузок данных значительно превышает число их изменений. Рассматриваемый в статье пример с пользовательским интерфейсом игры – как раз такой случай. При его создании требуется гибкость и легкость внесения изменений, но эти свойства совершенно не нужны в готовой игре (однако, с точки зрения производительности загрузки данных абсолютно никаких показаний к проведению такой оптимизации нет). Убрать (или существенно снизить) накладные расходы на гибкость позволяет использование входных данных не для непосредственного создания объектов логики, но для генерации узкоспециализированного кода, создающего эти объекты. При этом одна из возможных стратегий состоит в том, что на этапе активного изменения данных этот код генерируется, компилируется и исполняется налету (благо компиляция в Lua – весьма быстрый процесс), а после стабилизации в дистрибутиве приложения остается и используется только сгенерированный вариант. Простейший подход к такой кодогенерации – непосредственная замена кода создания объектов в реализации ключевых слов на формирование текста этого кода. При этом, все условные переходы переносятся из выполняемого кода в генерирующий, а также (по мере сил) производятся другие оптимизации на основе имеющейся на момент генерации кода информации об объектах и обо всей системе в целом. Если присутствуют какие-либо «декоративные» архитектурные прослойки между генерируемым кодом и конечным системным кодом, их тоже можно попытаться ликвидировать. Вероятно, наиболее эффективный с точки зрения возможностей оптимизации подход – построение и многопроходный анализ дерева данных, аналогичного дереву, показанному в листинге 3. Встроенный язык регулярных выражений Самый простой способ генерации текста (а, значит, и кода) в Lua существует благодаря развитой встроенной поддержке собственного языка регулярных выражений. Вот реализация функции smart_str, позволяющей заполнять строки-шаблоны конкретными значениями (в варианте, не требующем написания скобок): smart_str = function(str) return function(context) return string.gsub(str, “($%((.-)%)”, function(capture) local c = context[capture] if not c then error(“Context ‘” .. capture .. “’ not found”) end return tostring(c) |