1
1
import functools
2
2
import uuid
3
3
4
- from libc.stdint cimport uint64_t, uint8_t, int8_t
4
+ from libc.stdint cimport uint8_t, int8_t
5
5
from libc.string cimport memcpy, strncmp
6
6
7
7
8
8
# A more efficient UUID type implementation
9
- # (6-7x faster than the uuid.UUID).
10
-
9
+ # (6-7x faster than the starndard uuid.UUID):
10
+ #
11
+ # -= Benchmark results (less is better): =-
12
+ #
13
+ # std_UUID(bytes): 1.2368
14
+ # c_UUID(bytes): * 0.1645 (7.52x)
15
+ # object(): 0.1483
16
+ #
17
+ # std_UUID(str): 1.8038
18
+ # c_UUID(str): * 0.2313 (7.80x)
19
+ #
20
+ # str(std_UUID()): 1.4625
21
+ # str(c_UUID()): * 0.2681 (5.46x)
22
+ # str(object()): 0.5975
23
+ #
24
+ # std_UUID().bytes: 0.3508
25
+ # c_UUID().bytes: * 0.1068 (3.28x)
26
+ #
27
+ # std_UUID().int: 0.0871
28
+ # c_UUID().int: * 0.0856
29
+ #
30
+ # std_UUID().hex: 0.4871
31
+ # c_UUID().hex: * 0.1405
32
+ #
33
+ # hash(std_UUID()): 0.3635
34
+ # hash(c_UUID()): * 0.1564 (2.32x)
35
+ #
36
+ # dct[std_UUID()]: 0.3319
37
+ # dct[c_UUID()]: * 0.1570 (2.11x)
38
+ #
39
+ # std_UUID() ==: 0.3478
40
+ # c_UUID() ==: * 0.0915 (3.80x)
11
41
12
- cdef const char * _hexmap = b" 0123456789abcdef"
13
42
14
43
cdef char _hextable[256 ]
15
44
_hextable[:] = [
@@ -27,14 +56,7 @@ _hextable[:] = [
27
56
]
28
57
29
58
30
- cdef inline char i64_to_hex(uint64_t num, char * s):
31
- cdef uint8_t i
32
-
33
- for i in range (15 , - 1 , - 1 ):
34
- s[i] = _hexmap[num & 0x0F ]
35
- num >>= 4
36
-
37
- return 0
59
+ cdef std_UUID = uuid.UUID
38
60
39
61
40
62
cdef pg_uuid_bytes_from_str(str u, char * out):
@@ -142,26 +164,18 @@ cdef class UUID(__UUIDReplaceMe):
142
164
return uuid.SafeUUID.unknown
143
165
144
166
def __str__ (self ):
145
- cdef:
146
- uint64_t u
147
- char out[36 ]
148
-
149
- u = < uint64_t> hton.unpack_int64(self ._data)
150
- i64_to_hex(u, out)
151
- u = < uint64_t> hton.unpack_int64(self ._data + 8 )
152
- i64_to_hex(u, out + 20 )
153
-
154
- memcpy(out + 14 , out + 12 , 4 )
155
- memcpy(out + 9 , out + 8 , 4 )
156
- memcpy(out + 19 , out + 20 , 4 )
157
- out[8 ] = b' -'
158
- out[13 ] = b' -'
159
- out[18 ] = b' -'
160
- out[23 ] = b' -'
161
-
167
+ cdef char out[36 ]
168
+ tohex.uuid_to_str(self ._data, out)
162
169
return cpythonx.PyUnicode_FromKindAndData(
163
170
cpythonx.PyUnicode_1BYTE_KIND, < void * > out, 36 )
164
171
172
+ @property
173
+ def hex (self ):
174
+ cdef char out[32 ]
175
+ tohex.uuid_to_hex(self ._data, out)
176
+ return cpythonx.PyUnicode_FromKindAndData(
177
+ cpythonx.PyUnicode_1BYTE_KIND, < void * > out, 32 )
178
+
165
179
def __repr__ (self ):
166
180
return f" UUID('{self}')"
167
181
@@ -171,42 +185,42 @@ cdef class UUID(__UUIDReplaceMe):
171
185
def __eq__ (self , other ):
172
186
if type (other) is UUID:
173
187
return strncmp(self ._data, (< UUID> other)._data, 16 ) == 0
174
- if isinstance (other, uuid.UUID ):
188
+ if isinstance (other, std_UUID ):
175
189
return self .int == other.int
176
190
return NotImplemented
177
191
178
192
def __ne__ (self , other ):
179
193
if type (other) is UUID:
180
194
return strncmp(self ._data, (< UUID> other)._data, 16 ) != 0
181
- if isinstance (other, uuid.UUID ):
195
+ if isinstance (other, std_UUID ):
182
196
return self .int != other.int
183
197
return NotImplemented
184
198
185
199
def __lt__ (self , other ):
186
200
if type (other) is UUID:
187
201
return strncmp(self ._data, (< UUID> other)._data, 16 ) < 0
188
- if isinstance (other, uuid.UUID ):
202
+ if isinstance (other, std_UUID ):
189
203
return self .int < other.int
190
204
return NotImplemented
191
205
192
206
def __gt__ (self , other ):
193
207
if type (other) is UUID:
194
208
return strncmp(self ._data, (< UUID> other)._data, 16 ) > 0
195
- if isinstance (other, uuid.UUID ):
209
+ if isinstance (other, std_UUID ):
196
210
return self .int > other.int
197
211
return NotImplemented
198
212
199
213
def __le__ (self , other ):
200
214
if type (other) is UUID:
201
215
return strncmp(self ._data, (< UUID> other)._data, 16 ) <= 0
202
- if isinstance (other, uuid.UUID ):
216
+ if isinstance (other, std_UUID ):
203
217
return self .int <= other.int
204
218
return NotImplemented
205
219
206
220
def __ge__ (self , other ):
207
221
if type (other) is UUID:
208
222
return strncmp(self ._data, (< UUID> other)._data, 16 ) >= 0
209
- if isinstance (other, uuid.UUID ):
223
+ if isinstance (other, std_UUID ):
210
224
return self .int >= other.int
211
225
return NotImplemented
212
226
@@ -268,20 +282,6 @@ cdef class UUID(__UUIDReplaceMe):
268
282
def node (self ):
269
283
return self .int & 0xffffffffffff
270
284
271
- @property
272
- def hex (self ):
273
- cdef:
274
- uint64_t u
275
- char out[32 ]
276
-
277
- u = < uint64_t> hton.unpack_int64(self ._data)
278
- i64_to_hex(u, out)
279
- u = < uint64_t> hton.unpack_int64(self ._data + 8 )
280
- i64_to_hex(u, out + 16 )
281
-
282
- return cpythonx.PyUnicode_FromKindAndData(
283
- cpythonx.PyUnicode_1BYTE_KIND, < void * > out, 32 )
284
-
285
285
@property
286
286
def urn (self ):
287
287
return ' urn:uuid:' + str (self )
@@ -329,10 +329,10 @@ cdef class UUID(__UUIDReplaceMe):
329
329
#
330
330
assert UUID.__bases__ [0 ] is __UUIDReplaceMe
331
331
assert UUID.__mro__[1 ] is __UUIDReplaceMe
332
- cpython.Py_INCREF(uuid.UUID )
333
- cpython.PyTuple_SET_ITEM(UUID.__bases__ , 0 , uuid.UUID )
334
- cpython.Py_INCREF(uuid.UUID )
335
- cpython.PyTuple_SET_ITEM(UUID.__mro__, 1 , uuid.UUID )
332
+ cpython.Py_INCREF(std_UUID )
333
+ cpython.PyTuple_SET_ITEM(UUID.__bases__ , 0 , std_UUID )
334
+ cpython.Py_INCREF(std_UUID )
335
+ cpython.PyTuple_SET_ITEM(UUID.__mro__, 1 , std_UUID )
336
336
# </hack>
337
337
338
338
0 commit comments