On Thu, Oct 14, 2021 at 7:37 PM Jeremiah Vivian nohackingofkrowten@gmail.com wrote:
So I implemented these functions as operators in a downloaded source of CPython... the differences are insane! (Sorry if this produces nested quotes)
import timeit
# d + 1 vs list(d.values())[0]: 2133x speedup
timeit.main(['-s', "d = {x: x+1 for x in range(10000)}", "d + 1"])
2000000 loops, best of 5: 165 nsec per loop
timeit.main(['-s', "d = {x: x+1 for x in range(10000)}", "list(d.values())[0]"])
1000 loops, best of 5: 352 usec per loop
Insane speedup but what does it prove? That if you handcraft C code to do the precise and narrow feature you need, it's faster than a naive listification?
Try the actually-recommended way: next(iter(d)). See how much difference you get. Not having your hacked-on interpreter I can't fully test this, but in my test of vanilla, d[next(iter(d))] was three orders of magnitude faster than list(d.values())[0] - bringing it within cooee of your "d + 1" version. Neither form copes with the possibility of an empty dictionary, so for proper comparisons, you'd need to try/except it; although recent CPythons have very very low cost to a try block that doesn't end up catching anything, so it probably won't make a material difference.
You've created some *incredibly* arbitrary operators which have no justification other than "this operator isn't being used". Even if you *do* manage to see a two thousand to one speedup, that is a microoptimization that comes at an extremely steep readability penalty. In no way does this make mathematical sense as "adding 1 to the dictionary", nor does it parallel the way that other types behave, nor is it internally consistent (multiplying isn't repeated addition), nor is it particularly apt use of a symbol (like Path/str). And I suspect that your speedups are really in the order of 2:1, not 2000:1.
ChrisA