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 presque 13 ans
Surtout pas de XML :-D
#2 Mis à jour par Emmanuel GARETTE il y a presque 13 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 presque 13 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 presque 13 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 presque 13 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 presque 13 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 13 ans
- Statut changé de Résolu à Fermé
- Assigné à mis à Emmanuel GARETTE
Vu