4 ms·
Naive interpretation of the bytecode (not even pre-decoded, just a switch statement). And almost everything is resolved in the dynamic environment. for exampl
by PyComfy 9y ago
Naive interpretation of the bytecode (not even pre-decoded, just a switch statement).
And almost everything is resolved in the dynamic environment. for example,
a = foo.bar(b)
is actually
ldict = locals()
ldict['a'] = ldict['foo'].__getattribute__('bar')(ldict['b'])
- tom_mellior 9y agoThis is a bit misleading. You suggest that local variables are looked up by name in a dictionary, which is not the case. They are looked up by indexing into a C array, with the index being a constant in the bytecode. That's quite a lot simpler. Here is the corresponding code (look above for the definition of the GETLOCAL macro): https://github.com/python/cpython/blob/fc1ce810f1da593648b4d19e7d582a235ec1dd37/Python/ceval.c#L1066 https://github.com/python/cpython/blob/fc1ce810f1da593648b4d... So your code should be more like: locals[a_idx] = locals[foo_idx]->__getattribute__('bar')(locals[b_idx]) But this isn't a very good rendering of the thing because it doesn't show the many redundant reference count increment/decrement pairs every time you touch a variable. (Also, interpreter dispatch uses computed GOTOs instead of the plain switch on C compilers that support it.)
- PyComfy 9y agoah sorry. i did import dis dis.dis("a = foo.bar(b)") which gave 1 0 LOAD_NAME 0 (foo) 2 LOAD_ATTR 1 (bar) 4 LOAD_NAME 2 (b) 6 CALL_FUNCTION 1 8 STORE_NAME 3 (a) 10 LOAD_CONST 0 (None) 12 RETURN_VALUE
- tom_mellior 9y agoAh, OK. Yes, those LOAD_NAMEs are slower than LOAD_FAST. If you put the code into a function, you get this: >>> def f(foo, b): ... a = foo.bar(b) ... >>> dis.dis(f) 2 0 LOAD_FAST 0 (foo) 3 LOAD_ATTR 0 (bar) 6 LOAD_FAST 1 (b) 9 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 12 STORE_FAST 2 (a) 15 LOAD_CONST 0 (None) 18 RETURN_VALUE LOAD_FAST is the normal case for locals inside a function. Not sure off the top of my head where LOAD_NAME would be generated in normal usage (i.e. where you don't evaluate code from a string). Edit: Also, I'm talking about Python 3. Maybe you aren't.