Why does STORE_MAP not take a parameter?
Building argument lists and dicts in python entails the following opcode pattern: 1 0 BUILD_MAP 3 3 LOAD_CONST 0 (2) 6 LOAD_CONST 1 (1) 9 STORE_MAP 10 LOAD_CONST 2 (4) 13 LOAD_CONST 3 (3) 16 STORE_MAP 17 LOAD_CONST 4 (6) 20 LOAD_CONST 5 (5) 23 STORE_MAP Building lists on the other hand works like this: 1 0 LOAD_CONST 0 (1) 3 LOAD_CONST 1 (2) 6 LOAD_CONST 2 (3) 9 BUILD_LIST 3 Why not have BUILD_MAP work like BUILD_LIST? I.e., STORE_MAP takes a parameter n and adds the last n pairs of stack elements into the n-1 stack element (the dictionary). This means that the data would live on the stack until it is all suddenly transferred to the dict, but I'm not sure about the effect on performance (whether positive or negative). It does save on instruction cache misses. It should be an easy change to implement since all calls to BUILD_MAP could be replaced with "BUILD_MAP 1" and then optimized later. Best, Neil
On 01/21/2015 11:16 PM, Neil Girdhar wrote:
Why not have BUILD_MAP work like BUILD_LIST? I.e., STORE_MAP takes a parameter n and adds the last n pairs of stack elements into the n-1 stack element (the dictionary).
It probably wouldn't make much difference. Building a list is substantially cheaper if you have all the items on hand and can copy them in en masse. But adding an item to a dict entails quite a lot of overhead, since you need to hash the key, look for a free slot, etc. and this would likely swamp any gain from executing less bytecodes. And on the other side of the equation, evaluating the items one at a time requires less stack space, so the stack frame can be smaller. But as always, you can't be sure without measuring it, and this would be a good thing for someone interested to try out. -- Greg
In a function call with named arguments the code generated doesn't follow
that pattern:
dis.dis(lambda : f(a=1,b=2,c=3))
displays:
1 0 LOAD_GLOBAL 0 (foo)
3 LOAD_CONST 1 ('a')
6 LOAD_CONST 2 (1)
9 LOAD_CONST 3 ('b')
12 LOAD_CONST 4 (2)
15 LOAD_CONST 5 ('c')
18 LOAD_CONST 6 (3)
21 CALL_FUNCTION 768
24 RETURN_VALUE
so the problem is only about inlined dicts (somewhat common but not
ubiquitous as they are in Javascript).
Andrea
On Thu, Jan 22, 2015 at 12:57 AM, Greg Ewing
On 01/21/2015 11:16 PM, Neil Girdhar wrote:
Why not have BUILD_MAP work like BUILD_LIST? I.e., STORE_MAP takes a parameter n and adds the last n pairs of stack elements into the n-1 stack element (the dictionary).
It probably wouldn't make much difference. Building a list is substantially cheaper if you have all the items on hand and can copy them in en masse. But adding an item to a dict entails quite a lot of overhead, since you need to hash the key, look for a free slot, etc. and this would likely swamp any gain from executing less bytecodes. And on the other side of the equation, evaluating the items one at a time requires less stack space, so the stack frame can be smaller.
But as always, you can't be sure without measuring it, and this would be a good thing for someone interested to try out.
-- Greg
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ agriff%40tin.it
participants (3)
-
Andrea Griffini
-
Greg Ewing
-
Neil Girdhar