Re: mydis.disco() [BUG-FIX]

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Thu, 17 Mar 1994 01:27:07 -0500

Re: mydis.disco()

Lines like:
" >> 62 SET_LINENO 6"
were not handled correctly, because the code assumed the
output had a fixed number of fields.

change line:
if field[1:] and field[1] == 'SET_LINENO' :
to:
if 'SET_LINENO' in field:

FYI: At bottom, is what the dump of
tofile( 'tofile.dump', disco, tofile.func_code )
looks like.

One of the reasons for this whole exercise was to look
at the possibilities of postprocessing and optomizing
Python byte code. Even a casual look hints at several
possibilities. ( Although I don't yet have any analysis
of what they might save. ) Stripping line numbers out
of well debugged and tested code is one. The following
sequence suggests there are a few redundant operations
that could be peephole optomized out:

| sys.stdout, file = file, sys.stdout # 6

>> 62 SET_LINENO 6
65 LOAD_FAST 0
68 LOAD_NAME 5 (sys)
71 LOAD_ATTR 6 (stdout)
74 BUILD_TUPLE 2
77 UNPACK_TUPLE 2
80 LOAD_NAME 5 (sys)
83 STORE_ATTR 6 (stdout)
86 STORE_FAST 0

A naieve look ( not considering the different costs of
different bytecode instructions ) also give the impression
that:
import sys
...
sys.stdout
is more expensive than:
from sys import stdout
...
stdout
if sys.stdout is accessed repeatedly.
[ I guess that should have been obvious, but I hadn't really
thought about it before. ]

- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU>
- UVA Department of Molecular Physiology and Biological Physics

----------------------------
>>> tofile( 'tofile.dump', disco, tofile.func_code )
----------------------------
<code object tofile at 200750a8, file "./redirect.py", line 3>
co_code: 127 3 0 123 3 0 99 2 0 125 0 0 125 1 0 125 2 0 127 5 0 101 3 0 124 0 0 100 1 0 102 2 0 26 12 111 23 0 1 127 5 0 101 4 0 124 0 0 100 2 0 102 2 0 26 125 0 0 110 1 0 1 127 6 0 124 0 0 101 5 0 105 6 0 102 2 0 92 2 0 101 5 0 95 6 0 125 0 0 127 7 0 122 21 0 127 8 0 101 7 0 124 1 0 124 2 0 102 2 0 26 70 87 100 0 0 127 9 0 127 10 0 124 0 0 101 5 0 105 6 0 102 2 0 92 2 0 101 5 0 95 6 0 125 0 0 88 100 0 0 83
co_consts: [None, 'write', 'w', {'func': 1, 'args': 2, 'file': 0}]
co_filename: ./redirect.py
co_name: tofile
co_names: ['file', 'func', 'args', 'hasattr', 'open', 'sys', 'stdout', 'apply']

| def tofile( file, func, *args ): # 3

0 SET_LINENO 3
3 RESERVE_FAST 3 ({'func': 1, 'args': 2, 'file': 0})
6 UNPACK_VARARG 2 (args)
9 STORE_FAST 0
12 STORE_FAST 1
15 STORE_FAST 2

| if not hasattr( file, 'write' ) : file = open( file, 'w' ) # 5

18 SET_LINENO 5
21 LOAD_NAME 3 (hasattr)
24 LOAD_FAST 0
27 LOAD_CONST 1 ('write')
30 BUILD_TUPLE 2
33 BINARY_CALL
34 UNARY_NOT
35 JUMP_IF_FALSE 23 (to 61)
38 POP_TOP

| if not hasattr( file, 'write' ) : file = open( file, 'w' ) # 5

39 SET_LINENO 5
42 LOAD_NAME 4 (open)
45 LOAD_FAST 0
48 LOAD_CONST 2 ('w')
51 BUILD_TUPLE 2
54 BINARY_CALL
55 STORE_FAST 0
58 JUMP_FORWARD 1 (to 62)
>> 61 POP_TOP

| sys.stdout, file = file, sys.stdout # 6

>> 62 SET_LINENO 6
65 LOAD_FAST 0
68 LOAD_NAME 5 (sys)
71 LOAD_ATTR 6 (stdout)
74 BUILD_TUPLE 2
77 UNPACK_TUPLE 2
80 LOAD_NAME 5 (sys)
83 STORE_ATTR 6 (stdout)
86 STORE_FAST 0

| try: # 7

89 SET_LINENO 7
92 SETUP_FINALLY 21 (to 116)

| apply( func, args ) # 8

95 SET_LINENO 8
98 LOAD_NAME 7 (apply)
101 LOAD_FAST 1
104 LOAD_FAST 2
107 BUILD_TUPLE 2
110 BINARY_CALL
111 PRINT_EXPR
112 POP_BLOCK
113 LOAD_CONST 0 (None)

| finally: # 9

>> 116 SET_LINENO 9

| sys.stdout, file = file, sys.stdout # 10

119 SET_LINENO 10
122 LOAD_FAST 0
125 LOAD_NAME 5 (sys)
128 LOAD_ATTR 6 (stdout)
131 BUILD_TUPLE 2
134 UNPACK_TUPLE 2
137 LOAD_NAME 5 (sys)
140 STORE_ATTR 6 (stdout)
143 STORE_FAST 0
146 END_FINALLY
147 LOAD_CONST 0 (None)
150 RETURN_VALUE