Le datetime Python3 est plus rapide en spécifiant simplement le fuseau horaire

introduction

La bibliothèque standard standard pour la gestion du temps en Python est datetime. C'est une bibliothèque qui peut être utilisée sans aucun problème même si vous l'utilisez correctement, et vous n'avez même pas à vous soucier des performances si vous l'appelez un peu. Cependant, lorsqu'il est nécessaire de générer une date-heure des dizaines de milliers ou des dizaines de millions de fois, le goulot d'étranglement devient apparent.

Donc, j'ai trouvé que les performances peuvent être améliorées un peu en faisant attention à un petit détail, alors je voudrais vous le présenter.

La conclusion est que nous utiliserons la bibliothèque standard timezone pour générer datetime.

Conclusion

Tout à coup, écrivez seulement la conclusion. Après cela, veuillez voir si vous êtes intéressé. Je pense qu'il est préférable de générer datetime comme suit. Le point est de savoir s'il faut spécifier «timezone». .. .. C'est tout.

from datetime import datetime, timedelta, timezone

#Génération de fuseau horaire
JST = timezone(timedelta(hours=+9), 'JST')

# GOOD,Le fuseau horaire est spécifié. de bonne heure
datetime.now(JST)
datetime.fromtimestamp(Heure UNIX, JST)

# NG,Il utilise un temps dépendant de l'environnement. Lent par rapport à ne pas spécifier de fuseau horaire
datetime.now()
datetime.fromtimestamp(Heure UNIX)

Comparaison des performances

Immédiatement, je vais essayer de générer «datetime» par diverses méthodes. Mesurez le temps de traitement lorsque «datetime» est généré 10 millions de fois. Dans quelle mesure les performances changent selon que le fuseau horaire est spécifié ou non. J'espère que vous pourrez vous y référer.

Lorsqu'un fuseau horaire est spécifié

C'est le modèle le plus rapide (pour autant que je sache).

zikan1.py


from datetime import datetime, timedelta, timezone

JST = timezone(timedelta(hours=+9), 'JST')

for _ in range(10000000):
  datetime.now(JST)
$ time python zikan1.py
real	0m7.581s
user	0m7.167s
sys	0m0.114s

Il boucle 10 millions de fois et le résultat est de 7 secondes.

Si vous ne spécifiez pas de fuseau horaire

Si vous ne spécifiez pas le fuseau horaire, il sera légèrement plus lent. Légèrement. ..

zikan2.py


from datetime import datetime

for _ in range(10000000):
  datetime.now()
$ time python zikan2.py
real	0m9.609s
user	0m9.149s
sys	0m0.111s

C'est environ 9 secondes. C'est un peu tard.

Lorsque le fuseau horaire est spécifié par pytz

pytz est une bibliothèque souvent utilisée pour spécifier le fuseau horaire dans les séries Python2. C'est parce que Python2 n'a pas encore implémenté la classe timezone. .. ..

zikan3.py


import pytz
from datetime import datetime

# third party
JST = pytz.timezone('Asia/Tokyo')

# performance testing
for _ in range(10000000):
  datetime.now(JST)
$ time python zikan3.py
real	1m9.173s
user	1m6.999s
sys	0m0.584s

C'était beaucoup plus lent que prévu. Nous en discuterons plus tard.

Lorsque le fuseau horaire est spécifié dans la série Python2

Comme c'est une bonne idée, j'ai également essayé l'analyse comparative avec le système Python 2. Pour la série Python2, seule la classe d'interface pour le fuseau horaire appelée tzinfo est fournie, vous devez donc l'implémenter vous-même. Fastidieux. Le «pytz» est peut-être devenu populaire à cause du problème.

zikan4.py


from datetime import datetime, timedelta, tzinfo

class JST(tzinfo):
  def utcoffset(self, dt):
    return timedelta(hours=9)


  def dst(self, dt):
    return timedelta(0)


  def tzname(self, dt):
    return 'JST'

for _ in range(10000000):
  datetime.now(JST())
$ time python zikan3.py
real	0m55.416s
user	0m51.131s
sys	0m1.532s

lent. .. .. ..

résultat

Fuseau horaire spécifié (7s) <Fuseau horaire non spécifié (9s) <python2 (51s) <pytz (66s) C'est devenu un sentiment.

Histoire détaillée

Pourquoi pytz est si lent

La classe de fuseau horaire de la bibliothèque standard et la classe de fuseau horaire de pytz sont des classes d'implémentation de tzinfo. Cependant, il y a une différence entre le ciel et la terre en termes de performances. Pourquoi? Je n'ai pas trouvé de réponse définitive, mais quand je la profile, la différence entre les deux est évidente.

$ python -m cProfile -s cumtime zikan1.py
         10001072 function calls (10001061 primitive calls) in 9.107 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      2/1    0.000    0.000    9.107    9.107 {built-in method builtins.exec}
        1    3.149    3.149    9.107    9.107 zikan1.py:1(<module>)
 10000000    5.950    0.000    5.950    0.000 {built-in method now}
      3/1    0.000    0.000    0.009    0.009 <frozen importlib._bootstrap>:958(_find_and_load)
      3/1    0.000    0.000    0.009    0.009 <frozen importlib._bootstrap>:931(_find_and_load_unlocked)
$ python -m cProfile -s cumtime zikan3.py
         70022021 function calls (70021903 primitive calls) in 83.138 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     14/1    0.001    0.000   83.138   83.138 {built-in method builtins.exec}
        1    3.185    3.185   83.138   83.138 zikan5.py:1(<module>)
 10000000    9.225    0.000   79.868    0.000 {built-in method now}
 10000000   17.973    0.000   70.643    0.000 tzinfo.py:179(fromutc)
 20000000   43.347    0.000   43.347    0.000 {method 'replace' of 'datetime.datetime' objects}

La partie à laquelle je veux faire attention est lors de l'exécution de zikan3.py

10000000   17.973    0.000   70.643    0.000 tzinfo.py:179(fromutc)
20000000   43.347    0.000   43.347    0.000 {method 'replace' of 'datetime.datetime' objects}

C'est la partie de. pytz a été appelé datetime.replace () et a été exécuté 20 millions de fois. Non seulement cela, la fonction fromutc est appelée. En d'autres termes, le processus tz.fromutc (datetime.now (). Replace (tzinfo = tz)) est en cours d'exécution. Générer la date / heure de l'heure en UTC => Générer la date et l'heure avec le fuseau horaire => Convertir en date / heure du fuseau horaire. .. C'est vrai.

D'un autre côté, quand le fuseau horaire de la bibliothèque standard est donné comme argument, il semble que «{méthode intégrée maintenant}» traite ce côté, et bien que les spécifications internes soient inconnues, il semble traiter efficacement. Je peux te dire ça.

en conclusion

Au fait ... En d'autres termes, utilisons le fuseau horaire standard de la bibliothèque! c'est tout!

N'hésitez pas à signaler toute inexactitude telle que des erreurs typographiques.

Recommended Posts

Le datetime Python3 est plus rapide en spécifiant simplement le fuseau horaire
J'ai essayé d'utiliser le module Datetime de Python
À propos de la date et du fuseau horaire Python
Le cycle de publication de Python est plus rapide!
[Python] Qu'est-ce que @? (À propos des décorateurs)
[python] Quelle est la clé triée?
À quoi sert le trait de soulignement Python (_)?
Python ne génère pas d'erreurs ou de sortie simplement parce que le retrait est mal aligné
Téléchargez le fichier en spécifiant la destination de téléchargement avec Python & Selemiun & Chrome (version Windows)
python Comment notifier automatiquement par téléphone lorsque le système tombe en panne
Comment trier en spécifiant une colonne dans le tableau Python Numpy.
[Python] Qu'est-ce qui est hérité par l'héritage multiple?
[Python] Visualisez les informations acquises par Wireshark
[Python] Arrondissez avec juste l'opérateur
Où est écrit le processus d'instanciation python?
Installer en spécifiant la version avec pip
Qu'est-ce que "mahjong" dans la bibliothèque Python? ??
Lisez le fichier ligne par ligne avec Python
Lisez le fichier ligne par ligne avec Python
Lisez le fichier en spécifiant le code de caractère.
[python] [meta] Le type de python est-il un type?
Pandas du débutant, par le débutant, pour le débutant [Python]
Qu'est-ce qui est le plus rapide, le mélange Python ou l'échantillon?
Importez en spécifiant directement le chemin du répertoire
Pourquoi le découpage Python est représenté par un deux-points (:)
La réponse de "1/2" est différente entre python2 et 3
Qu'est-ce que wheezy dans l'image Docker Python?
Trier les éléments d'un tableau en spécifiant des conditions
Wagtail est le meilleur CMS pour Python! (Peut-être)
Spécification de la plage des tableaux ruby et python
À propos de la différence entre "==" et "is" en python
[Python] Trier la table par sort_values (pandas DataFrame)
Astuce BeautifulSoup: choisissez la balise en spécifiant le chemin
Ceci est le seul examen de base de Python ~ 1 ~
Spécification de la destination de chargement du module avec GAE python
Ceci est le seul examen de base de Python ~ 2 ~
Comment effacer les caractères générés par Python
Ceci est le seul examen de base de Python ~ 3 ~
[Python] Comment comparer la date / heure avec le fuseau horaire ajouté
Trier la liste des tuples en Python en spécifiant l'ordre croissant / décroissant de plusieurs clés