Evolution #5172
Changement de format du fichier config.eol
Description
Aujourd'hui nous utilisons ConfigObj pour charger un fichier de type INI.
La bibliothèque ne s'en sort pas correctement avec les variables UTF-8, le module de validation est plus que limité et les performances sont déplorables.
Il faudrait changer le format du fichier eol et/ou la bibliothèque de chargement du fichier.
Impératif :
- facilement sériablisable dans une base de donnée NoSQL ;
- rapide ;
- conserve les types.
Format les plus connus :
- xml
- json
- yaml
- pickle
Révisions associées
remplacement de configobj par cjson (voir si on reste sur cjson par la suite) (fixes #5172)
Historique
#1 Mis à jour par Daniel Dehennin il y a environ 11 ans
Surtout pas de XML :-D
#2 Mis à jour par Emmanuel GARETTE il y a environ 11 ans
YAML :
a={} for i in range(0, 10000): a[i] = {'value': 'super', 'owner': 'gen_config'} b={'unicode': u'test', 'integer': 1, 'intunicode': u'1', 'list': [u'unicode', 1, u'1', [u'uneautre']], 'boolean': True, 'none': None} import yaml def save(): yaml.dump(a, file('document.yaml', 'w')) def load(): yaml.load(file('document.yaml', 'r')) import hotshot from hotshot import stats prof = hotshot.Profile("hotshot_edi_stats") prof.runcall(save) prof.close() s = stats.load("hotshot_edi_stats") s.sort_stats("cumulative").print_stats() prof = hotshot.Profile("hotshot_edi_stats") prof.runcall(load) prof.close() s = stats.load("hotshot_edi_stats") s.sort_stats("cumulative").print_stats() yaml.dump(b, file('document2.yaml', 'w')) c = yaml.load(file('document2.yaml', 'r')) assert set(b) == set(c) for i in b.keys(): assert b[i] == c[i] assert type(b[i]) == type(c[i])
Enregistrement :
1730072 function calls (1530072 primitive calls) in 2.586 seconds
Chargement :
7040383 function calls (6960383 primitive calls) in 5.650 seconds
Dictionnaire avant/après chargement identique.
#3 Mis à jour par Emmanuel GARETTE il y a environ 11 ans
- Statut changé de Nouveau à Accepté
- % réalisé changé de 0 à 80
Voici le test complet :
a={} for i in range(0, 10000): a['c{}'.format(i)] = {'value': 'super', 'owner': 'gen_config'} b={'unicode': u'test', 'integer': 1, 'intunicode': u'1', 'list': [u'unicode', 1, u'1', [u'uneautre']], 'boolean': True, 'none': None, 'hehe': u'héhé'} import yaml, cjson, pickle def save(): if typ == 'cjson': fh=file('document.json', 'w') fh.write(cjson.encode(a)) fh.close() elif typ == 'yaml': yaml.dump(a, file('document.yaml', 'w')) elif typ == 'pickle': pickle.dump(a, file('document.pkl', 'w')) else: raise Exception('hu?') def load(): if typ == 'cjson': fh=file('document.json', 'r') c=cjson.decode(fh.read(), all_unicode=True) fh.close() elif typ == 'yaml': yaml.load(file('document.yaml', 'r')) elif typ == 'pickle': pickle.load(file('document.pkl', 'r')) else: raise Exception('hu?') import hotshot for typ in ['cjson', 'yaml', 'pickle']: print "==========save {}=========".format(typ) from hotshot import stats prof = hotshot.Profile("hotshot_edi_stats") prof.runcall(save) prof.close() s = stats.load("hotshot_edi_stats") s.sort_stats("cumulative").print_stats() for typ in ['cjson', 'yaml', 'pickle']: print "==========read {}=========".format(typ) prof = hotshot.Profile("hotshot_edi_stats") prof.runcall(load) prof.close() s = stats.load("hotshot_edi_stats") s.sort_stats("cumulative").print_stats() for typ in ['cjson', 'yaml', 'pickle']: print "==========compare {}=========".format(typ) if typ == 'cjson': fh=file('document2.json', 'w') fh.write(cjson.encode(b)) fh.close() fh=file('document2.json', 'r') c=cjson.decode(fh.read(), all_unicode=True) fh.close() elif typ == 'yaml': yaml.dump(b, file('document2.yaml', 'w')) c = yaml.load(file('document2.yaml', 'r')) elif typ == 'pickle': pickle.dump(b, file('document2.pkl', 'w')) c = pickle.load(file('document2.pkl', 'r')) else: raise Exception('hu?') print set(b) == set(c) for i in b.keys(): try: print b[i] == c[i] print type(b[i]) == type(c[i]) except KeyError: print False
Résultat :
==========save cjson========= 1 function calls in 0.010 seconds ==========save yaml========= 1730072 function calls (1530072 primitive calls) in 2.704 seconds ==========save pickle========= 230018 function calls (150018 primitive calls) in 0.164 seconds ==========read cjson========= 1 function calls in 0.004 seconds ==========read yaml========= 7050397 function calls (6970397 primitive calls) in 6.070 seconds ==========read pickle========= 130024 function calls in 0.150 seconds ==========compare cjson========= True [..] True ==========compare yaml========= True [..] True ==========compare pickle========= True [..] True
#4 Mis à jour par Emmanuel GARETTE il y a environ 11 ans
Résultat :
cjson est le plus rapide.
Pickle est spécifique à Python et je ne suis pas sûr que le fichier yaml soit lisible avec autre chose que python-json :
boolean: true hehe: "h\xE9h\xE9" integer: 1 intunicode: !!python/unicode '1' list: - !!python/unicode 'unicode' - 1 - !!python/unicode '1' - [!!python/unicode 'uneautre'] none: null unicode: !!python/unicode 'test'
Pour moi, le winner est ... "cjson" !
#5 Mis à jour par Emmanuel GARETTE il y a environ 11 ans
- Statut changé de Accepté à Résolu
- % réalisé changé de 80 à 100
Appliqué par commit 5c6f7368982c5d46e9aff06da0ad82b2f96440e7.
#6 Mis à jour par Emmanuel GARETTE il y a environ 11 ans
- Echéance mis à 26/04/2013
- Version cible mis à Eole 2.4-dev-3
- Début mis à 01/04/2013
#7 Mis à jour par Joël Cuissinat il y a presque 11 ans
- Statut changé de Résolu à Fermé
- Assigné à mis à Emmanuel GARETTE
Vu