ctypes anecdote (was: Re: [Python-Dev] The os module, unix and win32)
Thomas Heller
theller at python.net
Thu Jan 22 08:46:40 EST 2004
Guido van Rossum <guido at python.org> writes:
>> Another possibility: we'd get a lot more mileage out of simply
>> adding ctypes to the standard install. That would solve the
>> immediate popen problem, let us get rid of _winreg entirely (and
>> replace it with a pure Python version), and make future Win32
>> problems easier to solve.
>
> I don't know that a Python version of _winreg using ctypes would be
> preferable over a C version. I'd expect it to be slower, less
> readable than the C version, and more susceptible to the possibility
> of causing segfaults. (As for speed, I actually have a windows
> registry application where speed of access is important.)
Late followup, a potentially interesting anecdote:
I was challanged to find out how much slower ctypes coded registry calls
would be than the _winreg calls.
So I naively wrote this code:
"""
import _winreg, time
from ctypes import *
if 1:
start = time.time()
i = 0
name = c_buffer(256)
cchName = sizeof(name)
while 0 == windll.advapi32.RegEnumKeyA(_winreg.HKEY_CLASSES_ROOT, i,
name, cchName):
i += 1
print i, time.time() - start
if 1:
start = time.time()
i = 0
try:
while 1:
_winreg.EnumKey(_winreg.HKEY_CLASSES_ROOT, i)
i += 1
except WindowsError:
pass
print i, time.time() - start
"""
Would you have guessed the result?
"""
5648 0.0700001716614
5648 73.7660000324
"""
So the *ctypes* version was about 1000 times faster!
The comparison is not really right, the 'name' buffer creation must be
inside the loop, of course.
The real cause is that the _winreg version does a call to
RegQueryInfoKey() before calling RegEnumKey(), to find out the size of
the larest subkey's name, and this (internally in Windows) probably does
have to look at each subkey. So the loop above probably has quadratic
runtime behaviour, which explains the bad performance.
To get on-topic for python-dev again, it seems there is much room for
improvement, at least for the _winreg.EnumKey function.
Thomas
More information about the Python-Dev
mailing list