From 370e8cfbf55f1abc74943f75e2af9545d7c0d246 Mon Sep 17 00:00:00 2001
From: Grant Mathews <gmathews@atlassian.com>
Date: Thu, 1 Oct 2015 14:45:02 -0700
Subject: [PATCH] Cache results from regex_util.normalize

This should speed up applications that lean heavily on urlresolvers.reverse.
---
 django/utils/regex_helper.py | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py
index 4a697b2..4424ba0 100644
--- a/django/utils/regex_helper.py
+++ b/django/utils/regex_helper.py
@@ -7,6 +7,8 @@ should be good enough for a large class of URLS, however.
 """
 from __future__ import unicode_literals
 
+from threading import local
+
 from django.utils import six
 from django.utils.six.moves import zip
 
@@ -46,6 +48,8 @@ class NonCapture(list):
     Used to represent a non-capturing group in the pattern string.
     """
 
+_normalized = local()
+_normalized.results = {}
 
 def normalize(pattern):
     """
@@ -69,6 +73,13 @@ def normalize(pattern):
     resolving can be done using positional args when keyword args are
     specified, the two cannot be mixed in the same reverse() call.
     """
+    if pattern not in _normalized.results:
+        _normalized.results[pattern] = _normalize(pattern)
+
+    # Return a copy of the list to avoid corrupting the cache
+    return list(_normalized.results[pattern])
+
+def _normalize(pattern):
     # Do a linear scan to work out the special features of this pattern. The
     # idea is that we scan once here and collect all the information we need to
     # make future decisions.
-- 
2.2.1

