2009-11-12 2 views
33

Я хочу понять, почему the protocol buffers solution for .NET от Marc Gravell так же быстро, как есть.Как protobuf-net достигает респектабельной производительности?

Я могу понять, как оригинальное решение Google достигло своей производительности: оно предварительно создает оптимизированный код для сериализации объектов; Я написал сериализацию вручную и знаю, что можно писать довольно быстрый код таким образом, если вы избегаете размышлений. Но библиотека Marc - это временное решение, которое использует атрибуты и не создает сгенерированный код. Итак, как это работает ?

+4

Вы пробовали читаете источник? Или даже просить Марка прямо? – Lazarus

+0

Я пробовал и даже имел некоторые идеи, но если кто-то может дать быстрый ответ, было бы хорошо – MichaelT

+2

Я с удовольствием расскажу об этом часами ;-p Но мне придется подождать, пока я закончу работу ... –

ответ

41

protobuf-net использует стратегический паттерн; по мере необходимости (один раз только для каждого типа) он использует отражение для просмотра типов и строит набор сериализаторов (на основе общего интерфейса), которые он может использовать для сериализации и десериализации - так , когда используется, он просто перешагивает известный набор сериализаторов.

Внутри, что он пытается разумно использовать отражение при разговоре с членами; он использует Delegate.CreateDelegate, чтобы поговорить со свойствами, и DynamicMethod (и пользовательский IL), чтобы поговорить с полями (когда это возможно, это зависит от целевой структуры). Это означает, что он всегда говорит типов делегатов, а не только DynamicInvoke (что очень медленно).

не сойдя с умом, код имеет некоторые оптимизации (возможно, за счет читаемости) с точкой зрения:

  • местной byte[] буферизации (входные выходных потоки /)
  • с использованием фиксированного размера массивы (а не списки и т. д.); возможно, слишком много
  • с использованием дженериков, чтобы избежать боксерских
  • многочисленные твики/крутит/и т.д. вокруг бинарной обработки петель

Оглядываясь назад, я думаю, что я сделал ошибку на точке дженериков; сложность означала, что форсирование дженериков в систему bent it out of shape in a few places и активно вызывает некоторые серьезные проблемы (для сложных моделей) on compact framework.

У меня есть несколько конструкций (в моей голове только), чтобы реорганизовать это с помощью не являющихся -генерических интерфейсов, и вместо (подходящих рамок) больше использовать ILGenerator (мой первый выбор был бы Expression, но силы версия с более высокой версией). Проблема, однако, в том, что для этого потребуется значительное время, и до недавнего времени I've been pretty swamped.

В последнее время мне удалось start spending some time on protobuf-net again, так что, надеюсь, я очистку своего отставания от запросов и т. Д. И начнем с этого в ближайшее время. Это также мое намерение заставить его работать с моделями другими, чем с отражением (т. Е. Описывать проводное отображение отдельно).


и не вызывает каких-либо сгенерированный код

Я хотел бы также уточнить, что есть два (опционально) Codegen маршруты, если вы хотите использовать сгенерированный код; protogen.exe или VS add-in, разрешите создание кода из файла .proto.Но это не необходимо - это полезно, главным образом, если у вас есть существующий файл .proto или намерение взаимодействовать с другим языком (C++ и т. Д.) Для разработки по контракту.

-3

Его характеристики очень хорошие!

Вы можете видеть всестороннее сравнение между различными форматами, включая Protobuf проделанной Ме- http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/

Это сравнение включает в себя большие и малые образцы данных и различные форматы.

Один из тестов в моей пост- enter image description here

+0

Вопрос был о том, как была выполнена работа, а не о том, насколько она эффективна. –

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

  • Нет связанных вопросов^_^