You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2017-09-28.13:26:05.102>created_at=<Date2009-04-30.10:13:35.222>labels= ['library', 'performance']
title='uuid.uuid1() is too slow'updated_at=<Date2017-09-28.13:26:05.100>user='https://bugs.python.org/wangchun'
uuid.uuid1() currently uses two different ways to generate a uuid. If
the system call "uuid_generate_time" is available, uuid1() uses the
system call via the ctypes interface, otherwise, it uses pure Python
code to generate a uuid. The problem is, the C interface
"uuid_generate_time" is even slower than the Python code. The ctypes
interface is too slow. According to my test, it took 55 microseconds to
generate a uuid via ctypes interface but only 45 microseconds via the
Python code. I also tried to test the performance of the
"uuid_generate_time" C API itself. It takes C code 12 microseconds. Most
of the time were wasted on ctypes. I believe we need to drop ctypes and
write a Python extensions in C for this job.
Using the same test from Wang Chun:
before:
uuid1(1000000)
101.759 microseconds
after:
uuid1(1000000)
91.663 microseconds
The delays are clearly in the _byte array copying as indicated by the
test below:
>>> import sys, time, uuid
>>> defuu(n):
... t = time.time()
... for x inrange(n):
... uuid._uuid_generate_time_fast()
... print('%.3f microseconds'% ((time.time() - t) *1000000.0/ n))
...
[72265 refs]
>>> uu(1000000)
13.157 microseconds
[72267 refs]
I would expect fixing this for the ctypes version would have a similar
speedup.
grooverdan commented on Sep 1, 2009
grooverdanmannequin
Mannequin
More actions
to prove it a bit more - ctype benchmark
>>> import ctypes, ctypes.util
>>> defuu1(n):
... t = time.time()
... _buffer = ctypes.create_string_buffer(16)
... for x inrange(n):
... uuid._uuid_generate_time(_buffer)
... print('%.3f microseconds'% ((time.time() - t) *1000000.0/ n))
...
>>> uu1(1000000)
15.819 microseconds
rosslagerwall commented on Jan 22, 2011
rosslagerwallmannequin
Mannequin
More actions
Attached is a patch based on the original patch, meant to have better performance.
records a time of 38.5 microseconds unpatched (still using ctypes/libuuid) and a time of 16.5 microseconds afterwards.
uuid4() results in an improvement from 30 microseconds to 9 microseconds. From what I could see, what took the most time was the call to UUID() with a bytes object. That's why this patch passes in the uuid as a long.
It also fixes setup.py to check for the uuid.h header.
I agree that there is a maintenance cost associated with C extension modules. However, I would certainly be glad if it allowed us to eliminate uses of ctypes in this module because ctypes is quite unsafe and doesn't work well across platforms (though it is admittedly very convenient).
The original report says the ctypes call is slower than the python code used as a fallback. Would it not, then, be a performance improvement just to drop the ctypes call, without creating a new C module? Creating a C module would then be a separate enhancement issue if someone thought the performance improvement was enough to justify the module. Or maybe it could live in the os module?
Activity
wangchun commentedon Apr 30, 2009
uuid.uuid1() currently uses two different ways to generate a uuid. If
the system call "uuid_generate_time" is available, uuid1() uses the
system call via the ctypes interface, otherwise, it uses pure Python
code to generate a uuid. The problem is, the C interface
"uuid_generate_time" is even slower than the Python code. The ctypes
interface is too slow. According to my test, it took 55 microseconds to
generate a uuid via ctypes interface but only 45 microseconds via the
Python code. I also tried to test the performance of the
"uuid_generate_time" C API itself. It takes C code 12 microseconds. Most
of the time were wasted on ctypes. I believe we need to drop ctypes and
write a Python extensions in C for this job.
wangchun commentedon Apr 30, 2009
This is my test on another faster machine.
avassalotti commentedon Jul 6, 2009
Can you provide a patch?
grooverdan commentedon Sep 1, 2009
This is a slightly crude module version. The speedups were only 10%
Python 3.2a0 (py3k:74612M, Sep 1 2009, 18:11:58)
[GCC 4.3.2] on linux2
Using the same test from Wang Chun:
before:
uuid1(1000000)
101.759 microseconds
after:
uuid1(1000000)
91.663 microseconds
I would expect fixing this for the ctypes version would have a similar
speedup.
grooverdan commentedon Sep 1, 2009
rosslagerwall commentedon Jan 22, 2011
Attached is a patch based on the original patch, meant to have better performance.
On my PC, this:
records a time of 38.5 microseconds unpatched (still using ctypes/libuuid) and a time of 16.5 microseconds afterwards.
uuid4() results in an improvement from 30 microseconds to 9 microseconds. From what I could see, what took the most time was the call to UUID() with a bytes object. That's why this patch passes in the uuid as a long.
It also fixes setup.py to check for the uuid.h header.
serhiy-storchaka commentedon Dec 1, 2013
Instead hexadecimals in _long_from_uuid_t you can use _PyLong_FromByteArray.
However adding new C implemented module has hight cost. I doubt that the speed up of UUID generation is worth this cost.
avassalotti commentedon Dec 1, 2013
I agree that there is a maintenance cost associated with C extension modules. However, I would certainly be glad if it allowed us to eliminate uses of ctypes in this module because ctypes is quite unsafe and doesn't work well across platforms (though it is admittedly very convenient).
bitdancer commentedon Apr 9, 2015
The original report says the ctypes call is slower than the python code used as a fallback. Would it not, then, be a performance improvement just to drop the ctypes call, without creating a new C module? Creating a C module would then be a separate enhancement issue if someone thought the performance improvement was enough to justify the module. Or maybe it could live in the os module?
serhiy-storchaka commentedon Apr 9, 2015
See also bpo-11063 and bpo-20519.
serhiy-storchaka commentedon Apr 9, 2015
And bpo-15206. Python implementation has a drawback.
vstinner commentedon Sep 28, 2017
Hum, there are many open uuid issues which propose similar changes. I close this issue in favor of bpo-11063. Please continue the discussion there.