Как получается, что json сериализация настолько быстрее, чем yaml сериализация в Python?

У меня есть код, который полагается в большой степени на yaml для межъязыковой сериализации и при работе над ускорением некоторого материала, я заметил, что yaml был безумно медленным по сравнению с другими методами сериализации (например, рассол, json).

Таким образом, что действительно дует, мой ум - то, что json настолько быстрее, что yaml, когда вывод почти идентичен.

>>> import yaml, cjson; d={'foo': {'bar': 1}}
>>> yaml.dump(d, Dumper=yaml.SafeDumper)
'foo: {bar: 1}\n'
>>> cjson.encode(d)
'{"foo": {"bar": 1}}'
>>> import yaml, cjson;
>>> timeit("yaml.dump(d, Dumper=yaml.SafeDumper)", setup="import yaml; d={'foo': {'bar': 1}}", number=10000)
44.506911039352417
>>> timeit("yaml.dump(d, Dumper=yaml.CSafeDumper)", setup="import yaml; d={'foo': {'bar': 1}}", number=10000)
16.852826118469238
>>> timeit("cjson.encode(d)", setup="import cjson; d={'foo': {'bar': 1}}", number=10000)
0.073784112930297852

CSafeDumper PyYaml и cjson оба записаны в C, таким образом, он не похож, это - C по сравнению с проблемой скорости Python. Я даже добавил некоторые случайные данные к нему, чтобы видеть, делает ли cjson какое-либо кэширование, но это - все еще путь быстрее, чем PyYaml. Я понимаю, что yaml является надмножеством json, но как yaml сериализатор мог быть 2 порядками величины медленнее с таким простым входом?

52
задан Martin Thoma 4 July 2015 в 22:52
поделиться

3 ответа

В общем, не сложность вывода определяет скорость синтаксического анализа, а сложность принятого ввода. Грамматика JSON очень лаконична . Парсеры YAML сравнительно сложные , что приводит к увеличению накладных расходов.

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

Напротив, первоочередные задачи дизайна YAML - удобочитаемость и поддержка сериализации произвольных собственных структур данных.Таким образом, YAML допускает чрезвычайно удобочитаемые файлы, , но его сложнее генерировать и анализировать. Кроме того, YAML выходит за рамки типов данных с наименьшим общим знаменателем , требуя более сложной обработки при переходе между различными средами программирования.

Я не разработчик парсера YAML, поэтому я не могу говорить конкретно о порядках величин без некоторых данных профилирования и большого корпуса примеров. В любом случае не забудьте протестировать большое количество входных данных, прежде чем почувствовать себя уверенно в результатах тестов.

Обновление Упс, неправильно прочитал вопрос. :-( Сериализация может быть невероятно быстрой, несмотря на большую грамматику ввода; однако, просматривая исходный код, похоже, что сериализация на уровне Python PyYAML создает граф представления , тогда как simplejson кодирует встроенные типы данных Python непосредственно в фрагменты текста.

59
ответ дан 7 November 2019 в 09:12
поделиться

Говоря об эффективности, я некоторое время использовал YAML и почувствовал, что меня привлекает простота, которую приобретают в этом языке некоторые назначения имен/значений. Однако в процессе я то и дело спотыкался об одну из тонкостей YAML, тонкие вариации в грамматике, позволяющие писать особые случаи в более лаконичном стиле и тому подобное. В итоге, хотя грамматика YAML почти наверняка формально непротиворечива, у меня осталось ощущение "расплывчатости". Тогда я ограничил себя в том, чтобы не трогать существующий, рабочий код YAML и писать все новое в более обходном, отказоустойчивом синтаксисе - что заставило меня отказаться от всего YAML. В итоге YAML пытается выглядеть как стандарт W3C и создает небольшую библиотеку трудночитаемой литературы о своих концепциях и правилах.

Я считаю, что это гораздо больше интеллектуальных затрат, чем нужно. Посмотрите на SGML/XML: разработанный IBM в ревущие 60-е годы, стандартизированный ISO, известный (в урезанном и измененном виде) как HTML бесчисленным миллионам людей, документированный, документированный и еще раз документированный во всем мире. Появляется маленький JSON и убивает этого дракона. Как JSON смог стать настолько широко используемым за столь короткое время, имея всего лишь один скудный веб-сайт (и javascript-светило для его поддержки)? Дело в его простоте, в полном отсутствии сомнений в его грамматике, в легкости изучения и использования.

XML и YAML сложны для людей, и они сложны для компьютеров. JSON вполне дружелюбен и прост как для людей, так и для компьютеров.

20
ответ дан 7 November 2019 в 09:12
поделиться

Беглый взгляд на python-yaml показывает, что его дизайн намного сложнее, чем у cjson:

>>> dir(cjson)
['DecodeError', 'EncodeError', 'Error', '__doc__', '__file__', '__name__', '__package__', 
'__version__', 'decode', 'encode']

>>> dir(yaml)
['AliasEvent', 'AliasToken', 'AnchorToken', 'BaseDumper', 'BaseLoader', 'BlockEndToken',
 'BlockEntryToken', 'BlockMappingStartToken', 'BlockSequenceStartToken', 'CBaseDumper',
'CBaseLoader', 'CDumper', 'CLoader', 'CSafeDumper', 'CSafeLoader', 'CollectionEndEvent', 
'CollectionNode', 'CollectionStartEvent', 'DirectiveToken', 'DocumentEndEvent', 'DocumentEndToken', 
'DocumentStartEvent', 'DocumentStartToken', 'Dumper', 'Event', 'FlowEntryToken', 
'FlowMappingEndToken', 'FlowMappingStartToken', 'FlowSequenceEndToken', 'FlowSequenceStartToken', 
'KeyToken', 'Loader', 'MappingEndEvent', 'MappingNode', 'MappingStartEvent', 'Mark', 
'MarkedYAMLError', 'Node', 'NodeEvent', 'SafeDumper', 'SafeLoader', 'ScalarEvent', 
'ScalarNode', 'ScalarToken', 'SequenceEndEvent', 'SequenceNode', 'SequenceStartEvent', 
'StreamEndEvent', 'StreamEndToken', 'StreamStartEvent', 'StreamStartToken', 'TagToken', 
'Token', 'ValueToken', 'YAMLError', 'YAMLObject', 'YAMLObjectMetaclass', '__builtins__', 
'__doc__', '__file__', '__name__', '__package__', '__path__', '__version__', '__with_libyaml__', 
'add_constructor', 'add_implicit_resolver', 'add_multi_constructor', 'add_multi_representer', 
'add_path_resolver', 'add_representer', 'compose', 'compose_all', 'composer', 'constructor', 
'cyaml', 'dump', 'dump_all', 'dumper', 'emit', 'emitter', 'error', 'events', 'load', 
'load_all', 'loader', 'nodes', 'parse', 'parser', 'reader', 'representer', 'resolver', 
'safe_dump', 'safe_dump_all', 'safe_load', 'safe_load_all', 'scan', 'scanner', 'serialize', 
'serialize_all', 'serializer', 'tokens']

Более сложные конструкции почти всегда означают более медленные конструкции, а это намного сложнее, чем когда-либо понадобится большинству людей.

12
ответ дан 7 November 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: