Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e4e9cd4

Browse files
committed
Modify name conversion to be (hopefully) a bit more efficient.
Use a dictionary instead of a list to map objects to their offsets in a const/name tuple of a code object. XXX The conversion is perhaps incomplete, in that we shouldn't have to do the list2dict to start.
1 parent 5477f52 commit e4e9cd4

2 files changed

Lines changed: 104 additions & 34 deletions

File tree

Lib/compiler/pyassem.py

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ def sorter(a, b):
1515
l.sort(sorter)
1616
return l
1717

18+
def list2dict(l):
19+
d = {}
20+
for i in range(len(l)):
21+
d[l[i]] = i
22+
return d
23+
24+
def dict2list(d):
25+
l = [(v, k) for k, v in d.items()]
26+
l.sort()
27+
return [k for v, k in l]
28+
1829
class FlowGraph:
1930
def __init__(self):
2031
self.current = self.entry = Block()
@@ -326,13 +337,14 @@ def getContainedGraphs(self):
326337
class PyFlowGraph(FlowGraph):
327338
super_init = FlowGraph.__init__
328339

329-
def __init__(self, name, filename, args=(), optimized=0):
340+
def __init__(self, name, filename, args=(), optimized=0, klass=None):
330341
self.super_init()
331342
self.name = name
332343
self.filename = filename
333344
self.docstring = None
334345
self.args = args # XXX
335346
self.argcount = getArgCount(args)
347+
self.klass = klass
336348
if optimized:
337349
self.flags = CO_OPTIMIZED | CO_NEWLOCALS
338350
else:
@@ -445,14 +457,25 @@ def convertArgs(self):
445457
assert self.stage == FLAT
446458
self.consts.insert(0, self.docstring)
447459
self.sort_cellvars()
460+
461+
self.c_varnames = list2dict(self.varnames)
462+
self.c_names = list2dict(self.names)
463+
self.c_consts = list2dict(self.consts)
464+
self.c_closure = list2dict(self.closure)
465+
448466
for i in range(len(self.insts)):
449467
t = self.insts[i]
450468
if len(t) == 2:
451-
opname = t[0]
452-
oparg = t[1]
469+
opname, oparg = t
453470
conv = self._converters.get(opname, None)
454471
if conv:
455472
self.insts[i] = opname, conv(self, oparg)
473+
474+
self.varnames = dict2list(self.c_varnames)
475+
self.names = dict2list(self.c_names)
476+
self.consts = dict2list(self.c_consts)
477+
self.closure = dict2list(self.c_closure)
478+
456479
self.stage = CONV
457480

458481
def sort_cellvars(self):
@@ -468,12 +491,23 @@ def sort_cellvars(self):
468491
self.cellvars = self.cellvars + cells.keys()
469492
self.closure = self.cellvars + self.freevars
470493

471-
def _lookupName(self, name, list):
494+
def _lookupName(self, name, dict):
495+
i = dict.get(name, None)
496+
if i is None:
497+
i = dict[name] = len(dict)
498+
return i
499+
500+
def XXX_lookupName(self, name, list):
472501
"""Return index of name in list, appending if necessary"""
502+
# XXX It should be possible to replace this with some
503+
# dictionary operations, but not sure how
473504
t = type(name)
474505
for i in range(len(list)):
475-
# must do a comparison on type first to prevent UnicodeErrors
476-
if t == type(list[i]) and list[i] == name:
506+
# must do a comparison on type first to prevent UnicodeErrors
507+
# not clear that a dictionary would work, because we could
508+
# get UnicodeErrors on lookups
509+
elt = list[i]
510+
if isinstance(elt, t) and elt == name:
477511
return i
478512
end = len(list)
479513
list.append(name)
@@ -483,20 +517,21 @@ def _lookupName(self, name, list):
483517
def _convert_LOAD_CONST(self, arg):
484518
if hasattr(arg, 'getCode'):
485519
arg = arg.getCode()
486-
return self._lookupName(arg, self.consts)
520+
return self._lookupName(arg, self.c_consts)
487521

488522
def _convert_LOAD_FAST(self, arg):
489-
self._lookupName(arg, self.names)
490-
return self._lookupName(arg, self.varnames)
523+
self._lookupName(arg, self.c_names)
524+
return self._lookupName(arg, self.c_varnames)
491525
_convert_STORE_FAST = _convert_LOAD_FAST
492526
_convert_DELETE_FAST = _convert_LOAD_FAST
493527

494528
def _convert_LOAD_NAME(self, arg):
495-
return self._lookupName(arg, self.names)
529+
return self._lookupName(arg, self.c_names)
496530

497531
def _convert_NAME(self, arg):
498-
self._lookupName(arg, self.varnames)
499-
return self._lookupName(arg, self.names)
532+
if self.klass is None:
533+
self._lookupName(arg, self.c_varnames)
534+
return self._lookupName(arg, self.c_names)
500535
_convert_STORE_NAME = _convert_NAME
501536
_convert_DELETE_NAME = _convert_NAME
502537
_convert_IMPORT_NAME = _convert_NAME
@@ -509,15 +544,15 @@ def _convert_NAME(self, arg):
509544
_convert_DELETE_GLOBAL = _convert_NAME
510545

511546
def _convert_DEREF(self, arg):
512-
self._lookupName(arg, self.names)
513-
self._lookupName(arg, self.varnames)
514-
return self._lookupName(arg, self.closure)
547+
self._lookupName(arg, self.c_names)
548+
self._lookupName(arg, self.c_varnames)
549+
return self._lookupName(arg, self.c_closure)
515550
_convert_LOAD_DEREF = _convert_DEREF
516551
_convert_STORE_DEREF = _convert_DEREF
517552

518553
def _convert_LOAD_CLOSURE(self, arg):
519-
self._lookupName(arg, self.varnames)
520-
return self._lookupName(arg, self.closure)
554+
self._lookupName(arg, self.c_varnames)
555+
return self._lookupName(arg, self.c_closure)
521556

522557
_cmp = list(dis.cmp_op)
523558
def _convert_COMPARE_OP(self, arg):

Tools/compiler/compiler/pyassem.py

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ def sorter(a, b):
1515
l.sort(sorter)
1616
return l
1717

18+
def list2dict(l):
19+
d = {}
20+
for i in range(len(l)):
21+
d[l[i]] = i
22+
return d
23+
24+
def dict2list(d):
25+
l = [(v, k) for k, v in d.items()]
26+
l.sort()
27+
return [k for v, k in l]
28+
1829
class FlowGraph:
1930
def __init__(self):
2031
self.current = self.entry = Block()
@@ -326,13 +337,14 @@ def getContainedGraphs(self):
326337
class PyFlowGraph(FlowGraph):
327338
super_init = FlowGraph.__init__
328339

329-
def __init__(self, name, filename, args=(), optimized=0):
340+
def __init__(self, name, filename, args=(), optimized=0, klass=None):
330341
self.super_init()
331342
self.name = name
332343
self.filename = filename
333344
self.docstring = None
334345
self.args = args # XXX
335346
self.argcount = getArgCount(args)
347+
self.klass = klass
336348
if optimized:
337349
self.flags = CO_OPTIMIZED | CO_NEWLOCALS
338350
else:
@@ -445,14 +457,25 @@ def convertArgs(self):
445457
assert self.stage == FLAT
446458
self.consts.insert(0, self.docstring)
447459
self.sort_cellvars()
460+
461+
self.c_varnames = list2dict(self.varnames)
462+
self.c_names = list2dict(self.names)
463+
self.c_consts = list2dict(self.consts)
464+
self.c_closure = list2dict(self.closure)
465+
448466
for i in range(len(self.insts)):
449467
t = self.insts[i]
450468
if len(t) == 2:
451-
opname = t[0]
452-
oparg = t[1]
469+
opname, oparg = t
453470
conv = self._converters.get(opname, None)
454471
if conv:
455472
self.insts[i] = opname, conv(self, oparg)
473+
474+
self.varnames = dict2list(self.c_varnames)
475+
self.names = dict2list(self.c_names)
476+
self.consts = dict2list(self.c_consts)
477+
self.closure = dict2list(self.c_closure)
478+
456479
self.stage = CONV
457480

458481
def sort_cellvars(self):
@@ -468,12 +491,23 @@ def sort_cellvars(self):
468491
self.cellvars = self.cellvars + cells.keys()
469492
self.closure = self.cellvars + self.freevars
470493

471-
def _lookupName(self, name, list):
494+
def _lookupName(self, name, dict):
495+
i = dict.get(name, None)
496+
if i is None:
497+
i = dict[name] = len(dict)
498+
return i
499+
500+
def XXX_lookupName(self, name, list):
472501
"""Return index of name in list, appending if necessary"""
502+
# XXX It should be possible to replace this with some
503+
# dictionary operations, but not sure how
473504
t = type(name)
474505
for i in range(len(list)):
475-
# must do a comparison on type first to prevent UnicodeErrors
476-
if t == type(list[i]) and list[i] == name:
506+
# must do a comparison on type first to prevent UnicodeErrors
507+
# not clear that a dictionary would work, because we could
508+
# get UnicodeErrors on lookups
509+
elt = list[i]
510+
if isinstance(elt, t) and elt == name:
477511
return i
478512
end = len(list)
479513
list.append(name)
@@ -483,20 +517,21 @@ def _lookupName(self, name, list):
483517
def _convert_LOAD_CONST(self, arg):
484518
if hasattr(arg, 'getCode'):
485519
arg = arg.getCode()
486-
return self._lookupName(arg, self.consts)
520+
return self._lookupName(arg, self.c_consts)
487521

488522
def _convert_LOAD_FAST(self, arg):
489-
self._lookupName(arg, self.names)
490-
return self._lookupName(arg, self.varnames)
523+
self._lookupName(arg, self.c_names)
524+
return self._lookupName(arg, self.c_varnames)
491525
_convert_STORE_FAST = _convert_LOAD_FAST
492526
_convert_DELETE_FAST = _convert_LOAD_FAST
493527

494528
def _convert_LOAD_NAME(self, arg):
495-
return self._lookupName(arg, self.names)
529+
return self._lookupName(arg, self.c_names)
496530

497531
def _convert_NAME(self, arg):
498-
self._lookupName(arg, self.varnames)
499-
return self._lookupName(arg, self.names)
532+
if self.klass is None:
533+
self._lookupName(arg, self.c_varnames)
534+
return self._lookupName(arg, self.c_names)
500535
_convert_STORE_NAME = _convert_NAME
501536
_convert_DELETE_NAME = _convert_NAME
502537
_convert_IMPORT_NAME = _convert_NAME
@@ -509,15 +544,15 @@ def _convert_NAME(self, arg):
509544
_convert_DELETE_GLOBAL = _convert_NAME
510545

511546
def _convert_DEREF(self, arg):
512-
self._lookupName(arg, self.names)
513-
self._lookupName(arg, self.varnames)
514-
return self._lookupName(arg, self.closure)
547+
self._lookupName(arg, self.c_names)
548+
self._lookupName(arg, self.c_varnames)
549+
return self._lookupName(arg, self.c_closure)
515550
_convert_LOAD_DEREF = _convert_DEREF
516551
_convert_STORE_DEREF = _convert_DEREF
517552

518553
def _convert_LOAD_CLOSURE(self, arg):
519-
self._lookupName(arg, self.varnames)
520-
return self._lookupName(arg, self.closure)
554+
self._lookupName(arg, self.c_varnames)
555+
return self._lookupName(arg, self.c_closure)
521556

522557
_cmp = list(dis.cmp_op)
523558
def _convert_COMPARE_OP(self, arg):

0 commit comments

Comments
 (0)