Code


Version 16 (modified by Ludvig Ericson <ludvig.ericson@…>, 7 years ago) (diff)

--

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:

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:

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)

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.

psyco.profile(memory=2048) # roughly limit memory consumption to 2048Kb

See http://psyco.sourceforge.net/psycoguide/node14.html for more information

Instead of throwing an exception when the platform is wrong, one could just not start psyco.

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.