summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2016-03-21 17:18:05 +0100
committerStefan Behnel <stefan_ml@behnel.de>2016-03-21 17:22:03 +0100
commitdec1d449a5e4f9a389d9f2281907827b495d7e51 (patch)
tree2bf4056b4cb965b676d42ed4662bea5be08708f0
parent07fcb24b3b1b5eb942dd7507d0f8dd4ce1a7d990 (diff)
downloadcython-dec1d449a5e4f9a389d9f2281907827b495d7e51.tar.gz
speed up compilation for functions with large numbers of temps (already shows for a couple of thousand, e.g. for large list literals)
-rw-r--r--Cython/Compiler/Code.py20
1 files changed, 11 insertions, 9 deletions
diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py
index f11feed30..645d1f245 100644
--- a/Cython/Compiler/Code.py
+++ b/Cython/Compiler/Code.py
@@ -711,13 +711,14 @@ class FunctionState(object):
manage_ref = False
freelist = self.temps_free.get((type, manage_ref))
- if freelist is not None and len(freelist) > 0:
- result = freelist.pop()
+ if freelist is not None and freelist[0]:
+ result = freelist[0].pop()
+ freelist[1].remove(result)
else:
while True:
self.temp_counter += 1
result = "%s%d" % (Naming.codewriter_temp_prefix, self.temp_counter)
- if not result in self.names_taken: break
+ if result not in self.names_taken: break
self.temps_allocated.append((result, type, manage_ref, static))
self.temps_used_type[result] = (type, manage_ref)
if DebugFlags.debug_temp_code_comments:
@@ -736,11 +737,12 @@ class FunctionState(object):
type, manage_ref = self.temps_used_type[name]
freelist = self.temps_free.get((type, manage_ref))
if freelist is None:
- freelist = []
+ freelist = ([], set()) # keep order in list and make lookups in set fast
self.temps_free[(type, manage_ref)] = freelist
- if name in freelist:
+ if name in freelist[1]:
raise RuntimeError("Temp %s freed twice!" % name)
- freelist.append(name)
+ freelist[0].append(name)
+ freelist[1].add(name)
if DebugFlags.debug_temp_code_comments:
self.owner.putln("/* %s released */" % name)
@@ -751,7 +753,7 @@ class FunctionState(object):
used = []
for name, type, manage_ref, static in self.temps_allocated:
freelist = self.temps_free.get((type, manage_ref))
- if freelist is None or name not in freelist:
+ if freelist is None or name not in freelist[1]:
used.append((name, type, manage_ref and type.is_pyobject))
return used
@@ -779,7 +781,7 @@ class FunctionState(object):
"""
return [(cname, type)
for (type, manage_ref), freelist in self.temps_free.items() if manage_ref
- for cname in freelist]
+ for cname in freelist[0]]
def start_collecting_temps(self):
"""
@@ -2351,7 +2353,7 @@ class ClosureTempAllocator(object):
self.temps_free[type] = list(cnames)
def allocate_temp(self, type):
- if not type in self.temps_allocated:
+ if type not in self.temps_allocated:
self.temps_allocated[type] = []
self.temps_free[type] = []
elif self.temps_free[type]: