Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Several performance optimizations.

  • Loading branch information...
commit 916a65b9426b08c7d4e066da57a72e29e3dbf007 1 parent 780a87a
@BertrandBordage authored
Showing with 68 additions and 56 deletions.
  1. +34 −27 terms/html.py
  2. +30 −26 terms/managers.py
  3. +4 −3 terms/middleware.py
View
61 terms/html.py
@@ -8,44 +8,44 @@
from .exceptions import HTMLValidationWarning
+def concat_attrs(attrs):
+ return ''.join(' %s="%s"' % attr for attr in attrs)
+
+
class NeutralHTMLReconstructor(HTMLParser):
def reset(self):
HTMLParser.reset(self)
self.out = []
+ self.out__append = self.out.append
def feed(self, data):
data = self.unescape(data)
HTMLParser.feed(self, data)
self.out = ''.join(self.out)
- def concat_attrs(self, attrs):
- return ''.join(' %s="%s"' % (attr[0], attr[1]) for attr in attrs)
-
def handle_startendtag(self, tag, attrs):
- attrs = self.concat_attrs(attrs)
- self.out.append('<%s%s />' % (tag, attrs))
+ self.out__append('<%s%s />' % (tag, concat_attrs(attrs)))
def handle_starttag(self, tag, attrs):
- attrs = self.concat_attrs(attrs)
- self.out.append('<%s%s>' % (tag, attrs))
+ self.out__append('<%s%s>' % (tag, concat_attrs(attrs)))
def handle_endtag(self, tag):
- self.out.append('</%s>' % tag)
+ self.out__append('</%s>' % tag)
def handle_data(self, data):
- self.out.append(data)
+ self.out__append(data)
def handle_comment(self, data):
- self.out.append('<!--%s-->' % data)
+ self.out__append('<!--%s-->' % data)
def handle_decl(self, decl):
- self.out.append('<!%s>' % decl)
+ self.out__append('<!%s>' % decl)
def handle_pi(self, data):
- self.out.append('<?%s>' % data)
+ self.out__append('<?%s>' % data)
def unknown_decl(self, decl):
- self.out.append('<![%s]>' % decl)
+ self.out__append('<![%s]>' % decl)
class TermsHTMLReconstructor(NeutralHTMLReconstructor):
@@ -53,10 +53,13 @@ def reset(self):
NeutralHTMLReconstructor.reset(self)
self.tree_level = 0
self.opened_tags = []
+ self.opened_tags__append = self.opened_tags.append
+ self.opened_tags__pop = self.opened_tags.pop
self.disabled_level = None
self.variants_dict = Term.objects.variants_dict()
self.replace_dict = Term.objects.replace_dict()
self.replace_regexp = Term.objects.replace_regexp()
+ self.replace_regexp__sub = self.replace_regexp.sub
@property
def allow_replacements(self):
@@ -64,27 +67,30 @@ def allow_replacements(self):
def replace_terms(self, html):
def translate(match):
- before, name, after = match.group('before'), \
- match.group('name'), \
- match.group('after')
- replaced_name = self.replace_dict.get(name, name)
- if TERMS_REPLACE_FIRST_ONLY and name in self.replace_dict:
+ replace_dict = self.replace_dict
+ match_group = match.group
+ before, name, after = match_group('before'), \
+ match_group('name'), \
+ match_group('after')
+ replaced_name = replace_dict.get(name, name)
+ if TERMS_REPLACE_FIRST_ONLY and name in replace_dict:
for variant in self.variants_dict[name]:
- del self.replace_dict[variant]
+ del replace_dict[variant]
return before + replaced_name + after
-
- return self.replace_regexp.sub(translate, html)
+ return self.replace_regexp__sub(translate, html)
def handle_starttag(self, tag, attrs):
NeutralHTMLReconstructor.handle_starttag(self, tag, attrs)
- self.opened_tags.append((tag, self.get_starttag_text(), self.getpos()))
+ self.opened_tags__append((tag, self.get_starttag_text(),
+ self.getpos()))
self.tree_level += 1
dict_attrs = dict(attrs)
+ dict_attrs__get = dict_attrs.get
has_disabled_tag = tag in TERMS_IGNORED_TAGS
- classes = frozenset(dict_attrs.get('class', '').split())
+ classes = frozenset(dict_attrs__get('class', '').split())
has_disabled_class = not classes.isdisjoint(TERMS_IGNORED_CLASSES)
- has_disabled_id = dict_attrs.get('id', '') in TERMS_IGNORED_IDS
+ has_disabled_id = dict_attrs__get('id', '') in TERMS_IGNORED_IDS
if self.allow_replacements and (has_disabled_tag or has_disabled_class
or has_disabled_id):
@@ -92,7 +98,7 @@ def handle_starttag(self, tag, attrs):
def handle_endtag(self, tag):
try:
- opened_tag, full_start_tag, pos = self.opened_tags.pop()
+ opened_tag, full_start_tag, pos = self.opened_tags__pop()
# Adds the tag to HTML only if it has a start tag.
NeutralHTMLReconstructor.handle_endtag(self, tag)
except IndexError:
@@ -115,7 +121,8 @@ def handle_endtag(self, tag):
self.tree_level -= 1 # We suppose the start tag is a start-end tag
# with its final '/' missing.
- if self.disabled_level and self.disabled_level == self.tree_level:
+ disabled_level = self.disabled_level
+ if disabled_level and disabled_level == self.tree_level:
self.disabled_level = None
self.tree_level -= 1
@@ -123,4 +130,4 @@ def handle_endtag(self, tag):
def handle_data(self, data):
if self.allow_replacements:
data = self.replace_terms(data)
- self.out.append(data)
+ self.out__append(data)
View
56 terms/managers.py
@@ -6,42 +6,46 @@
import re
+VARIANTS_DICT_CACHE_KEY = 'terms__variants_dict'
REPLACE_DICT_CACHE_KEY = 'terms__replace_dict'
REPLACE_REGEXP_CACHE_KEY = 'terms__replace_regexp'
-CACHE_KEYS = REPLACE_DICT_CACHE_KEY, REPLACE_REGEXP_CACHE_KEY
+CACHE_KEYS = (VARIANTS_DICT_CACHE_KEY, REPLACE_DICT_CACHE_KEY,
+ REPLACE_REGEXP_CACHE_KEY)
class TermManager(Manager):
def variants_dict(self):
- d = {}
- for term in self.get_query_set().iterator():
- name_variants = term.name_variants()
- for variant in name_variants:
- d[variant] = name_variants
+ d = cache.get(VARIANTS_DICT_CACHE_KEY)
+ if d is None:
+ d = {}
+ for term in self.get_query_set().iterator():
+ name_variants = term.name_variants()
+ for variant in name_variants:
+ d[variant] = name_variants
+ cache.set(VARIANTS_DICT_CACHE_KEY, d)
return d
def replace_dict(self):
- d = cache.get(REPLACE_DICT_CACHE_KEY, {})
- if d:
- return d
- template = 'terms/term_replace.html'
- for term in self.get_query_set().iterator():
- url = term.get_absolute_url()
- name_variants = term.name.split('|')
- context = {'url': url,
- 'url_is_external': bool(term.url)}
- for name_variant in name_variants:
- context['name_variant'] = name_variant
- d[name_variant] = render_to_string(template, context)
- cache.set(REPLACE_DICT_CACHE_KEY, d)
+ d = cache.get(REPLACE_DICT_CACHE_KEY)
+ if d is None:
+ d = {}
+ template = 'terms/term_replace.html'
+ for term in self.get_query_set().iterator():
+ url = term.get_absolute_url()
+ name_variants = term.name.split('|')
+ context = {'url': url,
+ 'url_is_external': bool(term.url)}
+ for name_variant in name_variants:
+ context['name_variant'] = name_variant
+ d[name_variant] = render_to_string(template, context)
+ cache.set(REPLACE_DICT_CACHE_KEY, d)
return d
def replace_regexp(self):
- r = cache.get(REPLACE_REGEXP_CACHE_KEY, None)
- if r is not None:
- return r
- replace_dict = self.replace_dict()
- r = re.compile('(?P<before>^|\W)(?P<name>%s)(?P<after>\W|$)'
- % '|'.join(map(re.escape, replace_dict)))
- cache.set(REPLACE_REGEXP_CACHE_KEY, r)
+ r = cache.get(REPLACE_REGEXP_CACHE_KEY)
+ if r is None:
+ replace_dict = self.replace_dict()
+ r = re.compile('(?P<before>^|\W)(?P<name>%s)(?P<after>\W|$)'
+ % '|'.join(map(re.escape, replace_dict)))
+ cache.set(REPLACE_REGEXP_CACHE_KEY, r)
return r
View
7 terms/middleware.py
@@ -24,10 +24,11 @@ def process_response(self, request, response):
is_html = 'text/html' in response['Content-Type']
if not app_ignored and is_html and response.status_code == 200:
+ parser = self.parser
try:
- self.parser.feed(response.content.decode('utf-8'))
- response.content = self.parser.out
+ parser.feed(response.content.decode('utf-8'))
+ response.content = parser.out
finally:
- self.parser.reset()
+ parser.reset()
return response
Please sign in to comment.
Something went wrong with that request. Please try again.