🐷

Python3のdatetimeでtimezoneを指定すると早くなるとか言われてるけど、夏時間のせい

2 min read

タイムゾーンを指定すると高速になる....わけではない

Python3のdatetimeはタイムゾーンを指定するだけで高速になる - Qiita

記事ではプロファイラをつかってるが、python/3はソース公開してるので、ソースを眺めたほうが早い。処理を順に追いかけてみよう、

datetime.now()

    @classmethod
    def now(cls, tz=None):
        "Construct a datetime from time.time() and optional time zone info."
        t = _time.time()
        return cls.fromtimestamp(t, tz)

タイムゾーンは指定してないので、tz=Noneは確定だとして、
datetime.fromtimestamp(t,None)

    @classmethod
    def fromtimestamp(cls, t, tz=None):
        """Construct a datetime from a POSIX timestamp (like time.time()).
        A timezone info object may be passed in as well.
        """
        _check_tzinfo_arg(tz)

        return cls._fromtimestamp(t, tz is not None, tz)

ようやく本命 datetime._fromtimestamp(t,True,None)

   @classmethod
    def _fromtimestamp(cls, t, utc, tz):
        """Construct a datetime from a POSIX timestamp (like time.time()).
        A timezone info object may be passed in as well.
        """

この関数の中盤に、明確に tz is Noneに関する処理がある

        result = cls(y, m, d, hh, mm, ss, us, tz)
        if tz is None:
            # As of version 2015f max fold in IANA database is
            # 23 hours at 1969-09-30 13:00:00 in Kwajalein.
            # Let's probe 24 hours in the past to detect a transition:

githubの履歴をたどるとPEP495に対する修正であることがわかる

Closes issue #24773: Implement PEP 495 (Local Time Disambiguation). · python/cpython@5d0c598 · GitHub

PEP495

PEP495に関しては、オフィシャルで日本語訳が存在する。

What's New In Python 3.6 — Python 3.9.4 ドキュメント

世界の大抵の場所で、地域時計が1日繰り下げられることがこれまでありましたし、これからもあるでしょう。そういった時に、同じ日に同じ時間を指す区間があります。そういった状況では地域時計が表示する (あるいは Python の datetime インスタンスが格納する) 情報では、時間内の特定の瞬間を識別することはできません。
PEP 495 は時間内の地域時間が同じ二つの瞬間を区別するために、新たな fold 属性を datetime.datetime インスタンスならびに datetime.time クラスに追加しました。

早い話が、夏時間対応ということだ。

似たようなことはRubyでも起こるらしい。

環境変数を設定するだけでRuby on Railsサーバが10%高速化する(かもしれない)話 - Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Ruby の time.c を見てみると、 find_time_t 関数にてシステムの localtime_r に指定時刻の2時間前後の時刻を与えて、何が返ってくるかを調べています。これはどうやら、夏時間の切り替わりの際には同一の時刻が2回ある場合があるので、そういうときに必ず決まった側を返すための処理のようでした。

Discussion

ログインするとコメントできます