From: Meegan a. J. W. <wi...@af...> - 2004-05-19 19:01:27
|
Dear Psycotics, As an tool of Python evangelism, I attempted to Psyco-optimize a little graph searching algorithm I've written. Nodes and edges are essentially adorned tuples. The original implementation used "old style" classes, Python 2.2.2, Psyco 1.2 on vanilla RH9. Psyco "improved" the runtime on a sample data set from six to seven seconds. Because the Psyco docs advised using "new style classes", I engaged in five hours of hand-to-hand combat with their apparently bifurcated constructors (__init__(self,...) and __new__(cls,...), depending on whether or not the parent is mutable. I assume there's a good reason for this lunacy, but ours is not to reason why.) I emerged with a revised implementation using subclasses of "tuple", and eagerly reenabled Psyco. Same result. I've tried "import psyco" and "from psyco.classes import *" followed by either "psyco.profile()" or "psyco.full()". In the profile() case, "psyco.log()" reports that Psyco *seems* to be compiling certain methods. Curiously, it repeatedly "tags" a lambda expression each of the several times it exceeds a threshold "cost". I would have thought one compilation would have been enough. In the full() case, the log reports "Unsupported opcode 90 at <class_name>:6" for every single one of my new-style classes! Now the Psyco docs accuse me of generating a "STORE_NAME" instruction (whatever the heck that is) for the VM, but offers no advice on how to repent my sins. Any advice? Jim Wilson Gainesville, FL |
From: Armin R. <ar...@tu...> - 2004-05-23 21:01:01
|
Hello, On Wed, May 19, 2004 at 03:01:19PM -0400, Meegan and Jim Wilson wrote: > Psyco "improved" the runtime on a sample data set from six to seven seconds. Hum, there are a few reasons why Psyco can actually slow down even algorithmic code. It's very hard to tell of just one. It is a weakness of Psyco: it is hard to have any idea how it will perform. Could I have a look at the code? > I emerged with a revised implementation using subclasses of "tuple", and > eagerly reenabled Psyco. Same result. Argh. Sorry about the confusion. "New-style class" doesn't necessarily mean you have to subclass tuple. Usually it is just means that if you use classes at all, then whichever class you define with no bases should instead be declared to inherit from "object". Using "from psyco.classes import *" has the same result (and additionally calls psyco.bind() on these classes). > In the profile() case, "psyco.log()" reports that Psyco *seems* to be > compiling certain methods. Curiously, it repeatedly "tags" a lambda > expression each of the several times it exceeds a threshold "cost". The 'lambda' bit could highlight a weakness of Psyco (which I should document): *never* use map() or filter(). They kill the performance because they mean you are calling C code which calls back Python code (typically a lambda function). For complex reasons, there is a performance hit whenever the execution enters a function compiled by Psyco, which occurs for each element of the list with map() or filter(). You should use list comprehensions instead, e.g. result = [x*x for x in somelist if x>0] > In the full() case, the log reports "Unsupported opcode 90 at > <class_name>:6" for every single one of my new-style classes! Sorry for the confusion too. It only means that the creation of the class itself couldn't be accelerated. This is not a concern in general, as it is uncommon to create classes inside a loop. It doesn't mean that methods on the class will not be subsequently accelerated. I will complete the docs accordingly. A bientot, Armin. |