At 10:40 PM 10/17/03 +0200, Alex Martelli wrote: >Yes, def curry(func, arg): return new.instancemethod(func, arg, object) >IS indeed way more general than func.__get__(arg) [notably, you get to >call it repeatedly to curry more than one argument, from the left]. But >if you have to define a curry function anyway, it's not a huge win vs > >def curry(func, arg): > def curried(*args): return func(arg, *args) > return curried > >or indeed more general variations thereof such as > >def curry(func, *curried_args): > def curried(*args): return func(*(curried_args+args)) > return curried It is a big win if the curried function will be used in a performance-sensitive way. Instance method objects don't pay for setting up an extra frame object, and for the single curried argument, the interpreter even shortcuts some of the instancemethod overhead! So, if I were taking the time to write a currying function, I'd probably implement your latter version by chaining instance methods. (Of course, I'd also want to test to find out how many I could chain before the frame overhead was less than the chaining overhead.) Whenever I've run into a performance problem in Python (usually involving loops over 10,000+ items), I've almost invariably found that the big culprit is how many (Python) function calls happen in the loop. In such cases, execution time is almost linearly proportional to how many function calls happen, and inlining functions or resorting to a Pyrex version of the same function can often eliminate the performance problem on that basis alone. (For the Pyrex conversion, I have to use PyObject_GetAttr() in place of Pyrex's native attribute access, because it otherwise uses GetAttrString(), which seems to often make up for the lack of frame creation overhead.)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4