66 votes

Comment se fait-il que la sérialisation json soit tellement plus rapide que la sérialisation yaml en python?

J'ai un code qui s'appuie fortement sur yaml pour le contre-la langue de la sérialisation et tout en travaillant sur l'accélération de certains trucs, j'ai remarqué que yaml a été incroyablement lent par rapport à d'autres méthodes de sérialisation (par exemple, cornichon, json).

Ce qui a vraiment des coups de mon esprit, c'est que json est donc beaucoup plus rapide que yaml lorsque la sortie est à peu près identique.

>>> 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

PyYaml de CSafeDumper et cjson sont écrits en C, donc c'est pas comme si c'est un C vs Python problème de vitesse. J'ai même ajouté des données aléatoires pour voir si cjson est de faire toute la mise en cache, mais c'est encore de manière plus rapide que PyYaml. Je me rends compte que yaml est un sur-ensemble de json, mais comment le yaml sérialiseur être de 2 ordres de grandeur plus faible avec une telle entrée simple?

70voto

cdleary Points 18869

En général, ce n'est pas la complexité de la production qui détermine la vitesse de l'analyse, mais la complexité de la accepté de saisie. Le JSON grammaire est très concis. Le YAML analyseurs sont relativement complexes, conduisant à une augmentation des frais généraux.

JSON est avant tout objectif de conception est la simplicité et l'universalité. Ainsi, JSON est trivial pour générer et analyser, au prix de la réduction de l'homme la lisibilité. Il utilise également un plus bas le dénominateur commun de l'information de modèle, assurer toutes les données JSON peuvent être facilement traitées par chaque programmation moderne de l'environnement.

En revanche, YAML est avant tout la conception les objectifs sont de lisibilité et de soutien pour la sérialisation de l'arbitraire structures de données natif. Ainsi, YAML permet une grande lisibilité des fichiers, mais il est plus complexe à définir et l'analyser. En outre, YAML ventures au-delà du plus petit dénominateur commun types de données, nécessitant plus complexe le traitement lors de la traversée entre le les différents environnements de programmation.

Je ne suis pas un parseur YAML réalisateur, donc je ne peux pas parler spécifiquement pour les ordres de grandeur sans certains de profilage de données, et d'un grand corpus d'exemples. Dans tous les cas, assurez-vous de tester sur un grand corps d'entrées avant de se sentir confiant dans le nombre de référence.

Mise à jour Oups, mal lu la question. :-( Sérialisation peut encore être incroyablement rapide en dépit de la grande entrée de la grammaire; cependant, la navigation de la source, il ressemble à PyYAML du Python au niveau de la sérialisation construit une représentation graphique alors que simplejson code Python les types de données directement dans le texte des morceaux.

37voto

twosnac Points 90

Dans les applications que j'ai travaillé, le type d'inférence entre les chaînes de nombres (float/int) est l'endroit où la plus grande charge pour l'analyse de yaml est parce que les chaînes peuvent être écrites sans les guillemets. Parce que toutes les chaînes en json sont entre guillemets, il n'y a pas de retour en arrière lors de l'analyse des chaînes de caractères. Un excellent exemple où ce ralentissement est la valeur 0000000000000000000s. On ne peut pas dire que cette valeur est une chaîne de caractères jusqu'à ce que vous avez lu jusqu'à la fin de celui-ci.

Les autres réponses sont correctes, mais c'est un détail que j'ai découvert dans la pratique.

25voto

flow Points 1376

Parlant de l'efficacité, j'ai utilisé le format YAML pour un temps et se sentait attiré par la simplicité que certains nom/valeur des affectations prendre dans cette langue. Cependant, dans le processus, j'ai trébuché et si souvent à propos de l'un de YAML de finesses, de subtiles variations dans la grammaire qui vous permettent d'écrire des cas particuliers dans plus de style concis et ces. En fin de compte, bien que YAML la grammaire est presque pour certains formellement cohérent, il m'a laissé avec un certain sentiment de "caractère " vague". J'ai ensuite moi-même restreint à ne pas toucher existant, de travail YAML code et d'écrire tout ce qui est nouveau dans un plus rond-point, fail-safe de la syntaxe qui m'a fait abandonner toutes YAML. Le résultat est que YAML essaie de ressembler à un standard du W3C, et produit une petite bibliothèque de dur à lire de la littérature concernant ses concepts et ses règles.

Cela, je crois, est de loin la plus intellectuelle de ressources que nécessaire. Regardez SGML/XML: développé par IBM dans les années folles années 60, normalisé par l'ISO, connu (dans un simplifiés et forme modifiée) au format HTML pour d'innombrables millions de personnes, documentés et consignés et documentés de nouveau dans le monde entier. Vient peu JSON et tue le dragon. Comment pourrait-JSON devenu très largement utilisé en un temps aussi court, avec seulement un maigre site web (et un javascript luminaire pour)? Il est dans sa simplicité, la simple absence de doute dans sa grammaire, la facilité de l'apprentissage et de l'utiliser.

XML et YAML sont durs pour les humains, et ils sont durs pour ordinateurs. JSON est très convivial et facile à la fois les humains et les ordinateurs.

13voto

Glenn Maynard Points 24451

Un rapide coup d'œil à python-yaml suggère que sa conception est beaucoup plus complexe que celle de 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']
 

Les conceptions plus complexes impliquent presque toujours des conceptions plus lentes, ce qui est bien plus complexe que la plupart des gens n'en auront jamais besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X