| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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 scriptimport 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.
| Back | FazBrowse Home | New Git URL |
Activity
gh-128150: Improve performances of `uuid.uuid*` constructor functions. (