[pygccxml-development] Another way to speed up the generation process...
Brought to you by:
mbaas,
roman_yakovenko
|
From: Matthias B. <ba...@ir...> - 2006-10-20 16:22:46
|
Hi,
I just thought I'd share a little code snippet that can be useful to
speed up the bindings generation process. The below function simply
removes all declaration nodes that do not originate from the specified
directories (i.e. it removes all the system chunk that is not going to
be wrapped anyway). So you should call that function right after the
parsing step.
I noticed that these extra nodes can eat up a lot of time as I was
porting my script over to OSX where a lot more system headers are read.
On Linux the running time was reduced from about 4:40 minutes to around
3:20 minutes and on OSX it went down from 7:20 minutes to 4:10 minutes.
On OSX the top-level namespace contained more than 20000 nodes whereas
on Linux it was only about 4700 nodes. What I still have to investigate
is how the cache can be modified so that it stores the data *after*
pruning. It's a bit odd that reading the cache on OSX (14MB) takes more
than a minute whereas on Linux (6MB) it only takes 7 seconds. Obviously,
the algorithms used in the pickle module are far from being O(n).... ;)
- Matthias -
def pruneByHeader(rootdecl, includedirs):
"""Remove all nodes that don't originate from the specified
directories.
rootdecl must be the root node of the declaration tree (as a pygccxml
namespace_t object). All nodes right beneath the root who do not
originate from any directory in the list includedirs are removed
from the tree.
This operation is just meant to speed up subsequent queries
by removing anything that will not get wrapped anyway.
"""
includedirs = map(lambda x: os.path.abspath(x), includedirs)
num_decls = len(rootdecl.declarations)
num_removed = 0
for decl in rootdecl.declarations[:]:
header = getattr(decl.location, "file_name", None)
# Check if the decl should be kept. If it should, then continue
# the loop...
if header!=None:
header = os.path.abspath(header)
keep_it = False
for dir in includedirs:
if header.startswith(dir):
keep_it = True
break
if keep_it:
continue
# Remove the declaration
decl.parent.remove_declaration(decl)
num_removed += 1
print "%d out of %d top-level declarations removed (%d
kept)."%(num_removed, num_decls, num_decls-num_removed)
|