2013-12-03 6 views
1

Весь код, который я пишу (C++ или AS3), написан в значительной степени (JSON или XML). Моя проблема в том, что синтаксический анализ может быть очень медленным время от времени, особенно с менее мощными устройствами, такими как мобильные телефоны.Сценарий для двоичного преобразования и сериализации объектов

Вот пример Flash-скрипт шахты:

 <players class="fanlib.gfx.TSprite" vars="x=0|y=-50|visible=Bool:true"> 
      <player0 class="fanlib.gfx.TSprite" vars="x=131|y=138"> 
       <name class="fanlib.text.TTextField" format="Myriad Pro,18,0xffffff,true,,,,,center,,,,0" alignX="center" alignY="bottom" filters="DropShadow,2" vars="background=Bool:false|backgroundColor=0|embedFonts=Bool:true|multiline=Bool:false|mouseEnabled=Bool:false|autoSize=center|text=fae skata|y=-40"/> 
       <avatar class="fanlib.gfx.FBitmap" alignX="center" alignY="center" image="userDefault.png"/> 
       <chip class="fanlib.gfx.FBitmap" alignX="center" alignY="center" image="chip1.png" vars="x=87|y=68"/> 
       <info class="fanlib.text.TTextField" format="Myriad Pro,18,0xffffff,true,,,,,center,,,,0" alignX="center" alignY="top" filters="DropShadow,2" css=".win {color: #40ff40}" vars="y=40|background=Bool:false|backgroundColor=0|embedFonts=Bool:true|multiline=Bool:false|mouseEnabled=Bool:false|autoSize=center"/> 
      </player0> 

      <player1 class="Copy:player0" vars="x=430|y=70"> 
       <chip class="Child:chip" image="chip2.png" vars="x=-82|y=102"/> 
      </player1> 
      <player2 class="Copy:player0" vars="x=778|y=70"> 
       <chip class="Child:chip" image="chip3.png" vars="x=88|y=103"/> 
      </player2> 
      <player3 class="Copy:player0" vars="x=1088|y=137"> 
       <chip class="Child:chip" image="chip4.png" vars="x=-111|y=65"/> 
      </player3> 
      <player4 class="Copy:player0" vars="x=1088|y=533"> 
       <chip class="Child:chip" image="chip5.png" vars="x=-88|y=-23"/> 
      </player4> 
      <player5 class="Copy:player0" vars="x=585|y=585"> 
       <chip class="Child:chip" image="chip6.png" vars="x=82|y=-54"/> 
      </player5> 
      <player6 class="Copy:player0" vars="x=117|y=533"> 
       <chip class="Child:chip" image="chip7.png" vars="x=85|y=-26"/> 
      </player6> 
     </players> 

Сценарий выше создает «родной» (как в «нединамических») объектов флэш. TSprite является потомком Sprite, FBitmap наследуется от Bitmap и т. Д. При 71 КБ, для анализа на Sony XPeria требуется несколько десятков секунд.

Вместо того, чтобы оптимизировать синтаксический анализатор (который, вероятно, не будет слишком сильно увеличиваться), я рассматриваю преобразование своих сценариев в двоичные файлы, так что скрипты будут использоваться для отладки и завершенных двоичных файлов для выпускаемого кода.

Вопрос в том, как обрабатывать указатели с одного объекта на другой при их сериализации? Как переводчики из памяти в формат файла, совместимого с файлом, а затем обратно в память?

Другой вопрос, что относительно «вложенных» объектов? Например, во Flash объект может быть графическим контейнером других объектов. Может ли такое состояние быть сериализовано? Или объекты должны сохраняться отдельно и при загрузке с диска добавляются родителям через функции вложенности (т. Е. AddChild и т. Д.)?

Если возможно, я бы предпочел общие рекомендации, которые могут применяться к языкам, отличным от C++ или AS3.

+0

«Разбор занимает десятки секунд» означает буквально просто синтаксический анализ? Или включая создание объекта, как оно идет? Мы анализируем аналогичную сумму (возможно, немного больше) на мобильных устройствах, а время разбора на порядок быстрее. Это делает меня подозрительным в том, что делает ваш парсер. – AndySavage

+0

Вы правы, я имею в виду время, потраченное на всю судьбу. Плюс это быстрее, чем я изначально рассчитывал, но мой вопрос все еще остается. В конце концов, сериализация также должна ускорить создание объекта, поскольку они предварительно созданы ... или что-то в этом роде. –

+0

Я не согласен с вашим последним заявлением. Сериализация не имеет ничего общего со скоростью. Обычно это медленнее, чем создание объектов изначально, поскольку оно не должно обрабатывать служебные данные и (как правило) затраты на отражение. Единственным исключением из этого было бы создание объектов, которые были бы интенсивно вычислялись после вычисления, но это очевидно. Сколько объектов создается ваш скрипт 10s? Знаете ли вы, какие из них медленнее других? Я бы начал здесь. Либо посмотрите, как это исправить, либо, может быть, посмотрите на ленивый init некоторых из этих объектов, если это подходит. – AndySavage

ответ

3

Насколько я понял, ваша идея состоит в том, чтобы сэкономить время, заменив создание объектов из некоторого скрипта (xml/json) для десериализации (из двоичных) ранее сериализованных объектов. Если это так, я верю, что вы приняли неправильный подход для решения этой проблемы.

Поскольку вы попросили общие рекомендации, я попытаюсь объяснить свои рассуждения, а не слишком глубоко вникать в детали, специфичные для языка. Обратите внимание, что я расскажу об общем случае, и из него могут быть исключения. Нет серебряной пули, и вы должны проанализировать свой сценарий, чтобы выбрать лучшее решение для него.

С одной точки зрения создание множества объектов на основе атрибута/скрипта не отличается от десериализации объектов из двоичного. В конце концов, они оба превращают какое-то «сжатое» состояние в объекты, которые вы можете использовать. Да, это правда, что двоичные файлы обычно меньше по размеру, но форматы, такие как JSON, не так много накладных расходов в commomon case (XML обычно более избыточный). В целом вы не сэкономите много времени/памяти на deserializing это состояние из двоичного вместо синтаксический анализ это из скрипта. Вот пример реального мира от того, с чем я работал: Mental Ray - де-факто стандарт для рендеринга 3d-сцен \ спецэффектов в киноиндустрии. Он использует textual file format для представления сцен, которые во многом похожи на JSON. Mental Ray тяжело относится к вычислениям, производительность является одной из ключевых проблем здесь, но она отлично работает без бинарного файла формата сцены. Итак, анализируя этот аспект, вы можете сказать, что между этими двумя подходами нет существенной разницы.

С другой точки зрения, существует разница, которая может вступить в игру.В то время как десериализации объекта подразумевает только создания объекта и загрузки состояния в это полях, создавая объект из сценария может также включать в себя некоторые дополнительные инициализации на вершине этого. Таким образом, в некоторых случаях может быть полезно использование метода десериализации.

Однако, в конце концов, я бы сказал, что это не очень хорошая идея, чтобы просто replase ваших скриптовым объектов сериализованных объектов, потому что сценарии и сериализации являются концептуально разными вещами, и имеют разные цели (хотя у них есть что-то общее). Используя сериализационный подход, вы получите гибкость в изменении вашего фиксированного состояния (для людей, как правило, гораздо сложнее редактировать двоичные файлы вместо JSON/XML) , а также возможность выполнять инициализацию.

Итак, подумайте о том, что вам действительно нужно в вашем сценарии, и придерживайтесь его. Это лучший способ.

Теперь, если это случается, что вы на самом деле нужны ваши объекты, чтобы быть сценарий, но этот подход не достаточно быстро, я бы исследовать ускоряя его в одном из 2-х способов:

  1. Анализировать ли можно реструктурировать данные так, как это займет меньше времени для загрузки. Это не всегда возможно, однако, возможно, стоит попробовать.

  2. Проанализируйте, что делает ваш скриптовый движок для объекта init, за исключением простого создания и загрузки состояния в свои поля и попытайтесь его оптимизировать. Такой подход на самом деле имеет наибольший потенциал, поскольку это единственная часть, которая имеет существенное различие в показателях производительности (между сценарием и десериализационным подходом) и не приводит к неправильному использованию понятий. Попытайтесь выяснить, сможете ли вы сократить этот объем работы, необходимый для инициализации объекта. Может быть хорошей идеей адаптировать что-то более конкретное для ваших нужд, если вы в настоящее время используете какой-то общий механизм сценариев \ framework на данный момент.

Теперь, отвечая на ваши оригинальные вопросы ...

, как это одна ручка указателей от одного объекта к другому при сериализации их?

Рекомендации - головная боль Большинство реализаций сериализации не возится.

Один из подходов - использовать что-то для идентификации объекта во время сериализации (например, указатель), сериализовать объект, сохраняя это это удостоверение, и хранить ссылки от других объектов к этому объекту не как примитивный тип, а как ссылочный тип (в основном сохраняя идентичность). При десериализации - отслеживать все десериализованные объекты и повторно использовать их при десериализации заданного поля.

Как переводятся указатели из памяти на диск в формате файла, а затем обратно в память?

Это редкость, когда сериализация имеет дело с необработанной памятью. Этот подход хорош только для примитивных типов и не работает с поисковиками/рекомендациями. Языки, которые поддерживают отражение/интроспекцию, обычно используют его для проверки значений полей для сериализации объектов.Если мы говорим о чистом C++, где отражение плохое - нет другого надежного способа, кроме как заставить сам объект определять, чтобы сериализовать себя по потоку и использовать эти методы.

Другой вопрос, что относительно «вложенных» объектов? Например, во Flash объект может быть графическим контейнером других объектов. Может ли такое состояние быть сериализовано? Или объекты должны сохраняться отдельно и при загрузке с диска добавляются родителям через функции вложенности (т. Е. AddChild и т. Д.)?

Если мы говорим об десериализации - их, вероятно, следует рассматривать как ссылки (см. Ответ выше). Использование таких методов, как addChild, не является хорошей идеей, так как может содержать некоторую логику, которая будет беспорядочна.

Надеюсь, это ответит на ваши вопросы.

1

Вы должны взглянуть на Adobe Remote Object.

Обычно с помощью сериализации может стоить вам таких проблем, как:

  • У меня есть упорядоченный объект из приложения версии 2.3 и теперь в новой версии 2.4 было изменено: добавлено свойство удалено/свойство. Это делает мой сериализованный объект нецелесообразным.
  • При разработке протокола сериализации, который будет поддерживать кросс-платформу, вы действительно можете убить себя во время отладки. Я помню, как я это делал, и я потратил несколько часов, чтобы узнать, что моя вспышка с использованием Big Indian и C# с использованием Small Indian.

Adobe решить эти проблемы для вас, они создали хороший двоичный протокол называется AMF - Действие Формат сообщения. Он имеет множество реализаций на разных платформах, которые могут связываться с вашим скриптом действий.

Here вы можете найти некоторые реализации C++.

Смежные вопросы