diff --git a/include_cache/__init__.py b/include_cache/__init__.py index 4ef4196..2b8db6e 100644 --- a/include_cache/__init__.py +++ b/include_cache/__init__.py @@ -1,26 +1,21 @@ # A monkey patch for Django to cache which urlpattern was used to satifsy -# a resolve. By pushing that pattern to the front of the queue, we can get -# a real performance win on URLs deep in includes. - +# a resolve. By pushing that pattern to the front of the queue, we can +# avoid having Django loop through all the patterns. from django.core import urlresolvers from django.core.urlresolvers import ResolverMatch, Resolver404 -from django.utils.encoding import iri_to_uri, force_unicode, smart_str +from django.utils.encoding import smart_str _url_pattern_cache = {} + def resolve(self, path): tried = [] match = self.regex.search(path) if match: new_path = path[match.end():] patterns = self.url_patterns[:] - print self.url_patterns - print len(self.url_patterns) hint = _url_pattern_cache.get(path) - print _url_pattern_cache - print "hint moved..." - print hint if hint: patterns.insert(0, hint) for pattern in patterns: @@ -34,17 +29,24 @@ def resolve(self, path): tried.append([pattern]) else: if sub_match: - sub_match_dict = dict([(smart_str(k), v) for k, v in match.groupdict().items()]) + sub_match_dict = dict([(smart_str(k), v) for k, v + in match.groupdict().items()]) sub_match_dict.update(self.default_kwargs) for k, v in sub_match.kwargs.iteritems(): sub_match_dict[smart_str(k)] = v - _url_pattern_cache[path] = pattern + if path not in _url_pattern_cache: + _url_pattern_cache[path] = pattern - return ResolverMatch(sub_match.func, sub_match.args, sub_match_dict, sub_match.url_name, self.app_name or sub_match.app_name, [self.namespace] + sub_match.namespaces) + return ResolverMatch(sub_match.func, sub_match.args, + sub_match_dict, sub_match.url_name, + self.app_name or sub_match.app_name, + [self.namespace] + + sub_match.namespaces) tried.append([pattern]) raise Resolver404({'tried': tried, 'path': new_path}) - raise Resolver404({'path' : path}) + raise Resolver404({'path': path}) + def patch(): urlresolvers.RegexURLResolver.resolve = resolve diff --git a/readme.rst b/readme.rst index b952e72..3178f47 100644 --- a/readme.rst +++ b/readme.rst @@ -1,32 +1,32 @@ -django-cronjobs +django-include-cache ------------------ -This provide a @cron decorator to mark cronjob methods and -a namespace for managei. +If you've got a large number of includes in your Django urls.py, then there +can be a performance hit in accessing urls at the bottom of the includes as +Django searches through multiple url patterns to find the match. -Installation -================= +This monkey patches URLResolvers so that when the right pattern is found we +cache that pattern and move it to the top of the url pattern stack so it will +be found quicker. + +In completely unscientific tests on one site, before: -:: - pip install cronjobs +Requests per second: 438.49 [#/sec] (mean) -Add 'cronjobs' to your INSTALLED_APPS. +After: -Usage +Requests per second: 585.39 [#/sec] (mean) + +Installation ================= -Methods can be added to anywhere, but if you put them in a file called cron.py, -they will be automatically imported. +1. Install from pypi:: -Register you method by decorating it with @register for example:: - from cronjobs import register - @register - def some_function(): - pass + pip install django-include-cache -You can then run:: - manage.py cron some_function +2. In manage.py (or your wsgi script) add:: + import include_cache + include_cache.patch() -License: Mozilla Public License -Authors: originally by Jeff Balogh, packaged and broken by Andy McKay +Author: Andy McKay diff --git a/setup.py b/setup.py index a2c88e6..e4204a9 100644 --- a/setup.py +++ b/setup.py @@ -1,11 +1,10 @@ -from setuptools import setup, find_packages -import os +from setuptools import setup version = '0.1' setup(name='django-include-cache', version=version, - description="Cronjob helper for Django", + description="Include Cache for Django", long_description=open("readme.rst").read() + "\n", classifiers=[ 'Programming Language :: Python',