Merge lp:~kissiel/checkbox/speed-optimization into lp:checkbox

Proposed by Maciej Kisielewski
Status: Merged
Approved by: Maciej Kisielewski
Approved revision: 4520
Merged at revision: 4517
Proposed branch: lp:~kissiel/checkbox/speed-optimization
Merge into: lp:checkbox
Diff against target: 71 lines (+6/-8)
4 files modified
checkbox-ng/checkbox_ng/misc.py (+1/-1)
plainbox/plainbox/impl/session/state.py (+1/-1)
plainbox/plainbox/impl/unit/test_unit.py (+0/-3)
plainbox/plainbox/impl/unit/unit.py (+4/-3)
To merge this branch: bzr merge lp:~kissiel/checkbox/speed-optimization
Reviewer Review Type Date Requested Status
Po-Hsu Lin Approve
Paul Larson Approve
Review via email: mp+307553@code.launchpad.net

Description of the change

This MR is the first (and simple) patch set that improves plainbox startup time.

The speed-up depends on how many jobs there are in your provider 'database'.

Here are benchmarks from my slow NUC:

1000 jobs - 44s -> 24s
2500 jobs - 2m43s -> 1m19s

The benchmarks were done using this tool:
https://code.launchpad.net/~kissiel/+git/benchcbox/+ref/master

The tool generates providers and checkbox-cli launcher that doesn't run any of the jobs. Measuring wall time of running this launcher gives an estimate how long checkbox takes to 'spool up'.

To post a comment you must log in.
Revision history for this message
Paul Larson (pwlars) wrote :

Wow, part of me really wants to pick this apart and find if there are even more gains, compare it to normal sets, and things like that, but I see no reason to block such an obvious improvement for any time at all. It's hard to argue with those results, this is great!

review: Approve
Revision history for this message
Po-Hsu Lin (cypressyew) wrote :

Cool stuff, thanks.

review: Approve
Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :
Download full text (10.0 KiB)

The attempt to merge lp:~kissiel/checkbox/speed-optimization into lp:checkbox failed. Below is the output from the failed tests.

[precise] starting container
[precise] (timing) 0.11user 0.03system 0:05.50elapsed 2%CPU (0avgtext+0avgdata 9960maxresident)k
[precise] (timing) 0inputs+32outputs (0major+6827minor)pagefaults 0swaps
[precise] provisioning container
[precise] (timing) 45.51user 18.60system 1:07.10elapsed 95%CPU (0avgtext+0avgdata 97156maxresident)k
[precise] (timing) 0inputs+19168outputs (0major+3199615minor)pagefaults 0swaps
[precise-testing] Starting tests...
Found a test script: ./checkbox-ng/requirements/container-tests-checkbox-ng-unit
[precise-testing] container-tests-checkbox-ng-unit: FAIL
[precise-testing] stdout: http://paste.ubuntu.com/23278019/
[precise-testing] stderr: http://paste.ubuntu.com/23278020/
[precise-testing] (timing) Command exited with non-zero status 1
[precise-testing] (timing) 0.69user 0.14system 0:00.85elapsed 98%CPU (0avgtext+0avgdata 48608maxresident)k
[precise-testing] (timing) 0inputs+1280outputs (0major+22164minor)pagefaults 0swaps
Found a test script: ./checkbox-support/requirements/container-tests-checkbox-support
[precise-testing] container-tests-checkbox-support: PASS
[precise-testing] (timing) 31.22user 0.35system 0:31.61elapsed 99%CPU (0avgtext+0avgdata 150684maxresident)k
[precise-testing] (timing) 0inputs+1376outputs (0major+39712minor)pagefaults 0swaps
Found a test script: ./converged/requirements/container-tests-touch-unit-tests
[precise-testing] container-tests-touch-unit-tests: PASS
[precise-testing] (timing) 0.00user 0.02system 0:00.02elapsed 86%CPU (0avgtext+0avgdata 2232maxresident)k
[precise-testing] (timing) 0inputs+8outputs (0major+2345minor)pagefaults 0swaps
Found a test script: ./plainbox/plainbox/impl/providers/categories/requirements/container-tests-provider-categories
[precise-testing] container-tests-provider-categories: PASS
[precise-testing] (timing) 1.05user 0.09system 0:01.15elapsed 99%CPU (0avgtext+0avgdata 47200maxresident)k
[precise-testing] (timing) 0inputs+64outputs (0major+14466minor)pagefaults 0swaps
Found a test script: ./plainbox/requirements/001-container-tests-plainbox-egg-info
[precise-testing] 001-container-tests-plainbox-egg-info: PASS
[precise-testing] (timing) 0.22user 0.05system 0:00.28elapsed 98%CPU (0avgtext+0avgdata 14568maxresident)k
[precise-testing] (timing) 0inputs+88outputs (0major+6046minor)pagefaults 0swaps
Found a test script: ./plainbox/requirements/container-tests-plainbox
[precise-testing] container-tests-plainbox: PASS
[precise-testing] (timing) 38.72user 1.39system 0:40.26elapsed 99%CPU (0avgtext+0avgdata 201576maxresident)k
[precise-testing] (timing) 0inputs+3304outputs (0major+263264minor)pagefaults 0swaps
Found a test script: ./plainbox/requirements/container-tests-plainbox-documentation
[precise-testing] container-tests-plainbox-documentation: PASS
[precise-testing] (timing) 102.37user 0.59system 1:43.22elapsed 99%CPU (0avgtext+0avgdata 185420maxresident)k
[precise-testing] (timing) 0inputs+43216outputs (0major+58278minor)pagefaults 0swaps...

4520. By Maciej Kisielewski

checkbox-ng:misc: use expanded tuple for comparison

This way we check for 'not None' instead of going through full __eq__ chain.

Signed-off-by: Maciej Kisielewski <email address hidden>

Revision history for this message
Maciej Kisielewski (kissiel) wrote :

r.4520 fixes the failing test by unpacking (None, None) tuple and checking 'is not None' for both parts of the pair individually.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'checkbox-ng/checkbox_ng/misc.py'
--- checkbox-ng/checkbox_ng/misc.py 2016-03-11 13:46:41 +0000
+++ checkbox-ng/checkbox_ng/misc.py 2016-10-05 09:15:30 +0000
@@ -298,7 +298,7 @@
298 else:298 else:
299 tree.current_index += 1299 tree.current_index += 1
300 result = category.get_node_by_index(index, tree)300 result = category.get_node_by_index(index, tree)
301 if result != (None, None):301 if result[0] is not None and result[1] is not None:
302 return result302 return result
303 for job in self.jobs:303 for job in self.jobs:
304 if index == tree.current_index:304 if index == tree.current_index:
305305
=== modified file 'plainbox/plainbox/impl/session/state.py'
--- plainbox/plainbox/impl/session/state.py 2016-06-09 07:28:53 +0000
+++ plainbox/plainbox/impl/session/state.py 2016-10-05 09:15:30 +0000
@@ -413,7 +413,7 @@
413413
414 This method fires the :meth:`on_unit_added()` signal414 This method fires the :meth:`on_unit_added()` signal
415 """415 """
416 if unit in self._unit_list:416 if unit in frozenset(self._unit_list):
417 raise ValueError(417 raise ValueError(
418 _("attempting to add the same unit twice: %s" % unit.id))418 _("attempting to add the same unit twice: %s" % unit.id))
419 self.state.add_unit(unit)419 self.state.add_unit(unit)
420420
=== modified file 'plainbox/plainbox/impl/unit/test_unit.py'
--- plainbox/plainbox/impl/unit/test_unit.py 2016-05-20 13:54:59 +0000
+++ plainbox/plainbox/impl/unit/test_unit.py 2016-10-05 09:15:30 +0000
@@ -262,9 +262,6 @@
262 self.assertNotEqual(262 self.assertNotEqual(
263 Unit({}, parameters={'param': 'value1'}),263 Unit({}, parameters={'param': 'value1'}),
264 Unit({}, parameters={'param': 'value2'}))264 Unit({}, parameters={'param': 'value2'}))
265 # Ensure that units are not equal to other classes
266 self.assertTrue(Unit({}) != object())
267 self.assertFalse(Unit({}) == object())
268265
269 def test_get_accessed_parameters(self):266 def test_get_accessed_parameters(self):
270 # There are no accessed parameters if the unit is not parameterized267 # There are no accessed parameters if the unit is not parameterized
271268
=== modified file 'plainbox/plainbox/impl/unit/unit.py'
--- plainbox/plainbox/impl/unit/unit.py 2016-09-28 20:10:43 +0000
+++ plainbox/plainbox/impl/unit/unit.py 2016-10-05 09:15:30 +0000
@@ -383,6 +383,7 @@
383 self._checksum = None383 self._checksum = None
384 self._parameters = parameters384 self._parameters = parameters
385 self._virtual = virtual385 self._virtual = virtual
386 self._hash_cache = None
386387
387 @classmethod388 @classmethod
388 def instantiate_template(cls, data, raw_data, origin, provider, parameters,389 def instantiate_template(cls, data, raw_data, origin, provider, parameters,
@@ -405,8 +406,6 @@
405 field_offset_map)406 field_offset_map)
406407
407 def __eq__(self, other):408 def __eq__(self, other):
408 if not isinstance(other, Unit):
409 return False
410 return self.checksum == other.checksum409 return self.checksum == other.checksum
411410
412 def __ne__(self, other):411 def __ne__(self, other):
@@ -415,7 +414,9 @@
415 return self.checksum != other.checksum414 return self.checksum != other.checksum
416415
417 def __hash__(self):416 def __hash__(self):
418 return hash(self.checksum)417 if self._hash_cache is None:
418 self._hash_cache = int(self.checksum, 16)
419 return self._hash_cache
419420
420 @property421 @property
421 def unit(self):422 def unit(self):

Subscribers

People subscribed via source and target branches