Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 54e0004

Browse files
committed
Cache Parse() results
Each parse takes ~2ms on my machine, and it's pretty common throughout the life of a running process, to parse identical user-agent strings. This adds a very primitive cache similar in vein to the cache inside the `urlparse` package. Before: ``` $ python -m timeit -s 'from ua_parser.user_agent_parser import Parse' 'Parse("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.52 Safari/537.36")' 100 loops, best of 3: 2.14 msec per loop ``` After: ``` $ python -m timeit -s 'from ua_parser.user_agent_parser import Parse' 'Parse("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.52 Safari/537.36")' 1000000 loops, best of 3: 0.956 usec per loop ```
1 parent 112eefc commit 54e0004

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

Makefile

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
PWD = $(shell pwd)
2-
3-
all: prep test
1+
all: prep test
42

53
prep:
64
#git submodule update --init
75
#sudo apt-get install python-yaml
8-
6+
97
test:
108
@#test ! -d tmp && mkdir tmp
119
@export PYTHONPATH=tmp && python setup.py develop -d tmp
@@ -21,4 +19,4 @@ clean:
2119
@rm -rf tmp\
2220
ua_parser.egg-info
2321

24-
.PHONY: all clean
22+
.PHONY: all prep test clean

ua_parser/user_agent_parser.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ def Parse(self, user_agent_string):
196196
return device, brand, model
197197

198198

199+
MAX_CACHE_SIZE = 20
200+
_parse_cache = {}
201+
202+
199203
def Parse(user_agent_string, **jsParseBits):
200204
""" Parse all the things
201205
Args:
@@ -205,12 +209,20 @@ def Parse(user_agent_string, **jsParseBits):
205209
A dictionary containing all parsed bits
206210
"""
207211
jsParseBits = jsParseBits or {}
208-
return {
212+
key = (user_agent_string, repr(jsParseBits))
213+
cached = _parse_cache.get(key)
214+
if cached is not None:
215+
return cached
216+
if len(_parse_cache) > MAX_CACHE_SIZE:
217+
_parse_cache.clear()
218+
v = {
209219
'user_agent': ParseUserAgent(user_agent_string, **jsParseBits),
210220
'os': ParseOS(user_agent_string, **jsParseBits),
211221
'device': ParseDevice(user_agent_string, **jsParseBits),
212222
'string': user_agent_string
213223
}
224+
_parse_cache[key] = v
225+
return v
214226

215227

216228
def ParseUserAgent(user_agent_string, **jsParseBits):

0 commit comments

Comments
 (0)