Skip to content

Commit 7a00ccf

Browse files
committed
Optimize ObjectId.__str__()
Like #2656, I spotted this function taking ~0.9% of request time in a project using mongoengine. [`bytes.hex()`](https://docs.python.org/3/library/stdtypes.html#bytes.hex) was added in Python 3.5 and does the same as `binascii.hexlify(...).decode()` but faster, so I've replaced it here. (The `binascii.hexlify()` docs also now point to `bytes.hex()` as a faster alternative.) Benchmarked again using [`richbench`](https://github.com/tonybaloney/rich-bench) with the below script. <details> <summary><code>bench_objectid_str.py</code></summary> ```python from __future__ import annotations import binascii import os class ObjectIdBefore: __slots__ = ("__id",) def __init__(self) -> None: self.__id = os.urandom(12) def __str__(self) -> str: return binascii.hexlify(self.__id).decode() class ObjectIdAfter: __slots__ = ("__id",) def __init__(self) -> None: self.__id = os.urandom(12) def __str__(self) -> str: return self.__id.hex() test_oids_before = [ObjectIdBefore() for _ in range(100)] test_oids_after = [ObjectIdAfter() for _ in range(100)] def bench_str_before(): for oid in test_oids_before: for _ in range(100_000): str(oid) def bench_str_after(): for oid in test_oids_after: for _ in range(100_000): str(oid) __benchmarks__ = [ (bench_str_before, bench_str_after, "str(ObjectId) - hex conversion"), ] ``` </details> Results show a ~1.4x speedup: ``` $ uvx -p 3.13 richbench . Benchmarks, repeat=5, number=5 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Benchmark ┃ Min ┃ Max ┃ Mean ┃ Min (+) ┃ Max (+) ┃ Mean (+) ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ str(ObjectId) - hex conversion │ 3.000 │ 3.061 │ 3.019 │ 2.169 (1.4x) │ 2.231 (1.4x) │ 2.196 (1.4x) │ └────────────────────────────────┴─────────┴─────────┴─────────┴─────────────────┴─────────────────┴─────────────────┘ ```
1 parent 1e78bd4 commit 7a00ccf

File tree

1 file changed

+1
-2
lines changed

1 file changed

+1
-2
lines changed

bson/objectid.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"""Tools for working with MongoDB ObjectIds."""
1616
from __future__ import annotations
1717

18-
import binascii
1918
import datetime
2019
import os
2120
import struct
@@ -234,7 +233,7 @@ def __setstate__(self, value: Any) -> None:
234233
self.__id = oid
235234

236235
def __str__(self) -> str:
237-
return binascii.hexlify(self.__id).decode()
236+
return self.__id.hex()
238237

239238
def __repr__(self) -> str:
240239
return f"ObjectId('{self!s}')"

0 commit comments

Comments
 (0)