0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python 3.14】uuid モジュールが UUIDv7 に対応したので早速 time-serialized なID生成を試してみる

Last updated at Posted at 2025-10-13

㊗️ Python 3.14 リリース

2025-10-07 に Python 3.14 の stable がリリースされました!
機械学習で盛り上がった言語ですがそれ以前は数学と縁の深い言語の印象が強かったので 3.14 はテンション上がります❤️‍🔥

UUIDv6 / UUIDv7 / UUIDv8 サポート

New features を眺めてたら以下の記載を見つけてUUIDv6, UUIDv7, UUIDv8 のサポートを知ったので、今回は UUIDv7 の生成を試してみます。

UUID versions 6-8 are now supported by the uuid module, and generation of versions 3-5 are up to 40% faster.

特別意識するようなポイントではないですが 3.13 と 3.14 で参照している RFC が変わっているので頭の片隅に入れておこうと思います。

Python3.13

https://docs.python.org/3.13/library/uuid.html

uuid — UUID objects according to RFC 4122

Python 3.14

https://docs.python.org/3.14/library/uuid.html

uuid — UUID objects according to RFC 9562

UUIDv7 って何者

時間でソート可能なUUID文字列です。

vs. UUIDv4

広く使われてるID生成のアルゴリズムとして UUIDv4 があげられると思いますが、あちらは 生成アルゴリズム を見て分かるとおりバージョンを除く全てのフィールドがランダム値です。

例えばデータベース上でインデックス張ろうとしたけどカラムに格納しているのが UUID 文字列だったから効果が無くて涙を流した人もいるのではないでしょうか。

時間でソート可能な UUIDv7 は上記のようなシーンで効果が見込まれるかと思います。

詳しい説明やら各フィールドの意味やら生成アルゴリズムやらは RFC 9562 の 5.7. UUID Version 7 のセクションに記載があるので参照ください。

コード

5スレッド 5ループでそれぞれランダムな時間を待った後にUUIDv7 を発番してみます。

待ち時間はピコ秒のオーダーで実装していますが、以下の観点からこの精度は出ない想定です。

  • CPUのクロック周波数がギガヘルツのオーダーなのでこの一点においてはピコ秒の計測は理論上可能
  • OS含む他ソフトウェアのハードウェアリソース使用がボトルネックになり得る
  • CPython のランタイムがこの精度に耐え得るものか把握してない(調べるのめんどくさかった)からボトルネックの可能性があると考えるべき

なお、お試しなので PEP8 ガン無視の雑なコードです。

main.py
import random
import threading
import time
import uuid

result = []
lock = threading.Lock()


def generate_uuids(thread_id: int):
    for i in range(5):
        # WARN: 理論上クロック周波数的にはナノ秒の計測は可能だけど他ソフトウェアなりランタイムなりがボトルネックになって精度出ないと思う
        time.sleep(random.uniform(1/(10**9), 1/(10**6)))

        with lock:
            result.append(
                f"Thread {thread_id} - {i+1} times: UUID '{uuid.uuid7()}' generated ({(time.time() - START_TIME)*10**9:.0f} nano sec elasped)"
            )


if __name__ == "__main__":
    threads = []
    START_TIME = time.time()

    for i in range(5):
        thread = threading.Thread(target=generate_uuids, args=(i,))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    for i in result:
        print(i)

実行結果

結果を見るに、発番順序と生成されたIDの大小は一致してそうです。

$ python main.py
Thread 0 - 1 times: UUID '0199ddbf-1f13-7676-b9be-8f28d1d23e7b' generated (138998 nano sec elasped)
Thread 1 - 1 times: UUID '0199ddbf-1f14-7088-a626-e2fbcafa644f' generated (191927 nano sec elasped)
Thread 0 - 2 times: UUID '0199ddbf-1f14-7088-a626-e2fc6c9a10ad' generated (222921 nano sec elasped)
Thread 2 - 1 times: UUID '0199ddbf-1f14-7088-a626-e2fd6ce966de' generated (291824 nano sec elasped)
Thread 0 - 3 times: UUID '0199ddbf-1f14-7088-a626-e2fe99b37d41' generated (311852 nano sec elasped)
Thread 1 - 2 times: UUID '0199ddbf-1f14-7088-a626-e2ff291f38c6' generated (323772 nano sec elasped)
Thread 3 - 1 times: UUID '0199ddbf-1f14-7088-a626-e300684904df' generated (336885 nano sec elasped)
Thread 2 - 2 times: UUID '0199ddbf-1f14-7088-a626-e30157c47d97' generated (358820 nano sec elasped)
Thread 3 - 2 times: UUID '0199ddbf-1f14-7088-a626-e302ae9beecc' generated (396729 nano sec elasped)
Thread 1 - 3 times: UUID '0199ddbf-1f14-7088-a626-e3030c962a86' generated (407934 nano sec elasped)
Thread 0 - 4 times: UUID '0199ddbf-1f14-7088-a626-e304091a7a3e' generated (439167 nano sec elasped)
Thread 3 - 3 times: UUID '0199ddbf-1f14-7088-a626-e305091118b6' generated (454903 nano sec elasped)
Thread 1 - 4 times: UUID '0199ddbf-1f14-7088-a626-e3065c825b67' generated (471115 nano sec elasped)
Thread 2 - 3 times: UUID '0199ddbf-1f14-7088-a626-e3072529d40a' generated (489950 nano sec elasped)
Thread 1 - 5 times: UUID '0199ddbf-1f14-7088-a626-e3088cea433b' generated (503063 nano sec elasped)
Thread 4 - 1 times: UUID '0199ddbf-1f14-7088-a626-e309255ec55a' generated (530958 nano sec elasped)
Thread 3 - 4 times: UUID '0199ddbf-1f14-7088-a626-e30a08267c8f' generated (540018 nano sec elasped)
Thread 0 - 5 times: UUID '0199ddbf-1f14-7088-a626-e30b39cdf5d1' generated (552893 nano sec elasped)
Thread 4 - 2 times: UUID '0199ddbf-1f14-7088-a626-e30cc74b9633' generated (579834 nano sec elasped)
Thread 3 - 5 times: UUID '0199ddbf-1f14-7088-a626-e30d39411791' generated (587940 nano sec elasped)
Thread 2 - 4 times: UUID '0199ddbf-1f14-7088-a626-e30e1d697bea' generated (603914 nano sec elasped)
Thread 4 - 3 times: UUID '0199ddbf-1f14-7088-a626-e30f6895e80d' generated (627041 nano sec elasped)
Thread 2 - 5 times: UUID '0199ddbf-1f14-7088-a626-e3104f5a2bf8' generated (642776 nano sec elasped)
Thread 4 - 4 times: UUID '0199ddbf-1f14-7088-a626-e31126b166f5' generated (659943 nano sec elasped)
Thread 4 - 5 times: UUID '0199ddbf-1f14-7088-a626-e3120c7157cd' generated (676870 nano sec elasped)

ひとまず今回は同一マシン内でマルチスレッドにて検証しましたが、分散環境での動作検証も気になるところです。

あえて言うようなことでもないですが、タイムスタンプを根拠としている手前として分散環境においてはサーバ間で時刻が統一されていることが前提にあるかと思います。

他方で昨今主流のクラウドコンピューティング環境でマネージド使ってる限りはこのあたりのケアは関心の外かと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?