Projet

Général

Profil

Evolution #5172

Changement de format du fichier config.eol

Ajouté par Emmanuel GARETTE il y a environ 11 ans. Mis à jour il y a presque 11 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Début:
01/04/2013
Echéance:
26/04/2013
% réalisé:

100%

Temps passé:
Distribution:
EOLE 2.4

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

Révision 5c6f7368 (diff)
Ajouté par Emmanuel GARETTE il y a environ 11 ans

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

#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

Formats disponibles : Atom PDF