GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Improve performances of `uuid.*` functions · Issue #128150 · python/cpython

Improve performances of uuid.* functions #128150

New issue
Copy link
New issue
Copy link
Closed
Closed
Improve performances of uuid.* functions#128150
Copy link
Assignees
picnixz
Labels
performancePerformance or resource usagePerformance or resource usagestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

Description

@picnixz
picnixz
opened on Dec 21, 2024
Issue body actions

Feature or enhancement

The dedicated UUID constructors (e.g., uuid.uuid4()) generate bytes and pass them to the UUID constructor. However, the latter performs multiple and redundant checks. We can by-pass those checks since we are actually creating manually the UUID object. Here are the benchmarks for a PGO and python -OO (no LTO) build and a dedicated UUID.from_int constructor:

+----------------------------------------+---------+-----------------------+
| Benchmark                              | ref     | final                 |
+========================================+=========+=======================+
| uuid1(node, None)                      | 1.20 us | 1.16 us: 1.04x faster |
+----------------------------------------+---------+-----------------------+
| uuid1(None, clock_seq)                 | 1.16 us | 1.14 us: 1.02x faster |
+----------------------------------------+---------+-----------------------+
| uuid3(NAMESPACE_DNS, os.urandom(16))   | 1.13 us | 809 ns: 1.40x faster  |
+----------------------------------------+---------+-----------------------+
| uuid3(NAMESPACE_DNS, os.urandom(1024)) | 2.08 us | 1.73 us: 1.20x faster |
+----------------------------------------+---------+-----------------------+
| uuid4()                                | 1.16 us | 885 ns: 1.31x faster  |
+----------------------------------------+---------+-----------------------+
| uuid5(NAMESPACE_DNS, os.urandom(16))   | 1.15 us | 832 ns: 1.39x faster  |
+----------------------------------------+---------+-----------------------+
| uuid5(NAMESPACE_DNS, os.urandom(1024)) | 1.57 us | 1.27 us: 1.24x faster |
+----------------------------------------+---------+-----------------------+
| uuid8()                                | 952 ns  | 694 ns: 1.37x faster  |
+----------------------------------------+---------+-----------------------+
| Geometric mean                         | (ref)   | 1.21x faster          |
+----------------------------------------+---------+-----------------------+

Benchmark hidden because not significant (1): uuid1()

+----------------------------------------+---------+-----------------------+
| Benchmark                              | ref     | final                 |
+========================================+=========+=======================+
| uuid3(NAMESPACE_DNS, os.urandom(16))   | 1.13 us | 809 ns: 1.40x faster  |
+----------------------------------------+---------+-----------------------+
| uuid3(NAMESPACE_DNS, os.urandom(1024)) | 2.08 us | 1.73 us: 1.20x faster |
+----------------------------------------+---------+-----------------------+
| uuid4()                                | 1.16 us | 885 ns: 1.31x faster  |
+----------------------------------------+---------+-----------------------+
| uuid5(NAMESPACE_DNS, os.urandom(16))   | 1.15 us | 832 ns: 1.39x faster  |
+----------------------------------------+---------+-----------------------+
| uuid5(NAMESPACE_DNS, os.urandom(1024)) | 1.57 us | 1.27 us: 1.24x faster |
+----------------------------------------+---------+-----------------------+
| uuid8()                                | 952 ns  | 694 ns: 1.37x faster  |
+----------------------------------------+---------+-----------------------+
| Geometric mean                         | (ref)   | 1.31x faster          |
+----------------------------------------+---------+-----------------------+
Ignored benchmarks (3) of ref.json: uuid1(), uuid1(None, clock_seq), uuid1(node, None)

The above benchmarks keep constants as is since constant folding would remove the inefficiency of recomputing 1 << const everytime. With a hardcoded 1 << const, the numbers are (almost) identical.

I did not change the UUIDv1 generation because I observed that it would be worse in the uuid.uuid1() form (but 50% faster when either the node or the clock sequence is given, but this is likely not the usual call form).

Benchmark script
import os
import random
import uuid

import pyperf

if __name__ == '__main__':
    runner = pyperf.Runner()
    runner.bench_func('uuid1()', uuid.uuid1)
    node = random.getrandbits(48)
    runner.bench_func('uuid1(node, None)', uuid.uuid1, node)
    clock_seq = random.getrandbits(14)
    runner.bench_func('uuid1(None, clock_seq)', uuid.uuid1, None, clock_seq)

    ns = uuid.NAMESPACE_DNS
    runner.bench_func('uuid3(NAMESPACE_DNS, os.urandom(16))',
                      uuid.uuid3, ns, os.urandom(16))
    runner.bench_func('uuid3(NAMESPACE_DNS, os.urandom(1024))',
                      uuid.uuid3, ns, os.urandom(1024))

    runner.bench_func('uuid4()', uuid.uuid4)

    ns = uuid.NAMESPACE_DNS
    runner.bench_func('uuid5(NAMESPACE_DNS, os.urandom(16))',
                      uuid.uuid5, ns, os.urandom(16))
    runner.bench_func('uuid5(NAMESPACE_DNS, os.urandom(1024))',
                      uuid.uuid5, ns, os.urandom(1024))

    runner.bench_func('uuid8()', uuid.uuid8)

I'll submit a PR and we can decide what to keep and what to remove for maintainibility purposes. Note that the uuid module has been improved a lot performance-wise especially in terms of import time but I believe that constructing UUIDs objects via their dedicated functions.

Linked PRs

  • gh-128150: improve performances of uuid.uuid* constructor functions. #128151

Activity

  1. picnixz
    added
    type-featureA feature request or enhancementA feature request or enhancement
    performancePerformance or resource usagePerformance or resource usage
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Dec 21, 2024
  2. picnixz
    self-assigned this
    on Dec 21, 2024
  3. picnixz
    added a commit that references this issue on Jan 13, 2025

    gh-128150: Improve performances of `uuid.uuid*` constructor functions. (

    6ff8f82
  4. picnixz
    closed this as completedon Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @picnixz
    picnixz

Labels

performancePerformance or resource usagePerformance or resource usagestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402520 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.