Skip to content

Commit

Permalink
Fixed slowness in unicodeTestIn script used by keyword template.
Browse files Browse the repository at this point in the history
Fixes #125

This contains performance tests, which are ignored by default, but can be activated by exporting a number:
$ export AT_UNICODETESTIN=3000
$ bin/test -s Products.Archetypes -m test_widgets -t test_unicodeTestIn
...
Testing unicodeTestIn with 3000 items, and 50 selected.
...

Timings before this fix:

First test part finished in 4.2931 seconds
Second test part finished in 12.6825 seconds

Timings after this fix:

First test part finished in 0.0373 seconds
Second test part finished in 0.2010 seconds

And with the fix and 30,000 items:

First test part finished in 0.0374 seconds
Second test part finished in 2.0301 seconds
  • Loading branch information
mauritsvanrees committed Apr 9, 2019
1 parent ab1335e commit 63287b4
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
9 changes: 5 additions & 4 deletions Products/Archetypes/skins/archetypes/unicodeTestIn.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

if vocab is None or len(vocab) == 0:
return 0

value = context.unicodeEncode(value)
if not isinstance(value, str):
value = value.encode('utf-8')
for v in vocab:
if context.unicodeEncode(v) == value:
if not isinstance(v, str):
v = v.encode('utf-8')
if v == value:
return True

return False
37 changes: 31 additions & 6 deletions Products/Archetypes/tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,38 @@ def test_unicodeTestIn(self):
# The unicodeTestIn script can be called very often on edit
# forms when you have lots of keywords (Subject) in your site.
# So an interesting test here is: how fast is this? For a
# speed test, uncomment the next few lines. It basically
# tests having 3000 keywords, of which 50 are selected on a
# page. The related change in unicodeTestIn speeds this up
# speed test, run the tests with 'export AT_UNICODETESTIN=3000'.
# It basically tests having 3000 keywords, of which 50 are selected
# on a page. The related change in unicodeTestIn speeds this up
# from 42 to 15 seconds.
#vocab += [str(x) for x in range(3000)]
# for x in range(1000, 1050):
# self.assertEqual(self.portal.unicodeTestIn(str(x), vocab), True)
# And 9 years later it is 4.4 seconds for only this first part.
# And 0.03 seconds after some simple fixes to the script.
number = int(os.getenv('AT_UNICODETESTIN', 0))
if not number:
return
from time import time
print('\nTesting unicodeTestIn with {0} items, 50 selected.'.format(
number))
vocab += [str(x) for x in range(number)]
value = [str(x) for x in range(1000, 1050)]
time1 = time()
for v in value:
self.assertEqual(self.portal.unicodeTestIn(v, vocab), True)
time2 = time()
print('First test part finished in {0:.4f} seconds'.format(
time2 - time1))

# This is actually more how it is used:
# a large vocabulary, which is compared with a much smaller
# list of selected items. Originally took 12.6 seconds for 3000 items.
# And 0.2 seconds after some simple fixes.
for v in vocab:
# Some of these are True, others False, so we don't test the outcome.
# We only call this to test the speed.
self.portal.unicodeTestIn(v, value)
time3 = time()
print('Second test part finished in {0:.4f} seconds'.format(
time3 - time2))

def _test_widgets(self):
doc = makeContent(self.folder, portal_type='ComplexType', id='demodoc')
Expand Down
2 changes: 2 additions & 0 deletions news/125.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed slowness in ``unicodeTestIn`` script used by keyword template.
[maurits]

0 comments on commit 63287b4

Please sign in to comment.