= Fundamental problems = Using Psyco with Django is fundamentally problematic and requires thorough testing for the following warning listed in http://psyco.sourceforge.net/psycoguide/bugs.html#bugs: * Built-ins are assumed never to change. Global variables can change, of course, but you must not add or remove a global variable to shadow or expose a built-in (at least not after a module is initialized). * Do not dynamically change the methods of the new-style classes (classes that inherit from a built-in type). * Psyco assumes that types never change. This is basically wrong (you can assign to `__class__`). This might cause Psyco to randomly believe that instances are still of their previous type. However, Django uses metaprogramming and dynamic class changing throughout the code. Somebody should volunteer to test a reasonably complex Django application under Psyco, the testing roadmap should be as follows: * thoroughly test correct behaviour * compare performance with and withough Psyco * compare memory usage with and without Psyco = The middleware = {{{ #!python class PsycoMiddleware(object): """ Enables the psyco extension module which can massively speed up the execution of any Python code. """ def process_request(self, request): try: import psyco psyco.profile() except ImportError: pass return None }}} Note that you can use `psyco.full()` instead of `psyco.profile()`. See http://psyco.sourceforge.net/psycoguide/node8.html '''Note that Psyco should only be used on 32bit systems'''. See http://www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks . One possible way to determine the architecture automatically: {{{ #!python from platform import architecture if architecture()[0] != '32bit': raise Exception("Don't use this on non-32-bit platforms") class PsycoMiddleware(object): """ This middleware enables the psyco extension module which can massively speed up the execution of any Python code. """ def process_request(self, request): try: import psyco psyco.profile() except ImportError: pass return None }}} ---- One more issue I have with this -- why is import done on every request as opposed to module load time? The following looks saner to me: {{{ #!python from platform import architecture if architecture()[0] != '32bit': raise Exception("Don't use this on non-32-bit platforms") # let ImportError propagate at module load time so that people can notice and fix it import psyco class PsycoMiddleware(object): """ This middleware enables the psyco extension module which can massively speed up the execution of any Python code. """ def process_request(self, request): psyco.profile() return None }}} Or even (that's how I use it, and according to `psyco.log()` it seems to work) {{{ #!python import psyco # psyco.log() -- uncomment this if you want to see how psyco performs psyco.cannotcompile(re.compile) psyco.profile() class PsycoMiddleware(object): pass }}} See http://psyco.sourceforge.net/psycoguide/tutknownbugs.html#tutknownbugs for `cannotcompile()`. Note about memory consumption: You can limit the memory that psyco takes to compile code. This can be help full on limited memory systems in conjunction with mod_python apache prefork. {{{ #!python psyco.profile(memory=2048) # roughly limit memory consumption to 2048Kb }}} See http://psyco.sourceforge.net/psycoguide/node14.html for more information [http://www.repairpartstock.com/products-xx.asp?id=1699 360 xbox Controller] Instead of throwing an exception when the platform is wrong, one could just not start psyco. {{{ #!python import psyco import platform import re if platform.architecture()[0] == '32bit': psyco.cannotcompile(re.compile) # re.compile doesn't benefit from psyco psyco.profile() # psyco.profile seems like the most sane choice. # The middleware class definition is just here so django doesn't whine. # Note also that we placed this class outside the if so that # the middleware can be used without effect. class PsycoMiddleware(object): """ Enables the psyco extension module which can massively speed up the execution of any Python code. """ pass }}} = Known problems = Psyco is great and you should look into it, but sometimes it can create weird problems (in conjunction with other software) that may be hard to debug. Please remember to turn it off when you have strange / not so obvious problems. To alleviate such problem, you could change `if plat...` to `if not settings.DEBUG and plat...`, having done `from django.conf import settings` first, short example {{{ #!python from django.conf import settings import psyco import platform import re if not settings.DEBUG and platform.architecture()[0] == '32bit': # Enable psyco, like earlier. # Define middleware, like earlier. }}} This will simply disable psyco when you've got DEBUG set to True, which probably is a desirable effect. Combining regular classes in your Django models: class foo(object) and enabling psyco can generate this error: descriptor '__dict__' for 'Empty' objects doesn't apply to 'BaseQuery' object. A nice fix is discussed at: [http://www.fioca.com/brian/] (see: Fix for psyco in Django 1.0 query module)