]> git.cworth.org Git - apitrace/commitdiff
trim: Use custom skiplist for required list (instead of std::set<unsigned>)
authorCarl Worth <cworth@cworth.org>
Wed, 22 Aug 2012 18:59:12 +0000 (11:59 -0700)
committerCarl Worth <cworth@cworth.org>
Fri, 12 Apr 2013 21:30:38 +0000 (14:30 -0700)
The std::set<unsigned>::insert method has been dominating profile
output for trimming large traces. Meanwhile, the access patterns of
TraceAnalyzer on the required list is extremely structured; it often
adds the next sequential integer. So we can optimize this data
structure dramatically with two additions:

  1. Store ranges rather than single elements, so that the addition of
     a new number can expand an existing range rather than inserting a
     new element.

  2. Remember the most recent element looked-up so that we can check
     it first and not do any new lookup for in-order accesses.

With these two changes we get O(1) behavior for the access pattern of
adding sequential integers. For other cases we can still get
logarithmic behavior, but we can keep N dramatically smaller.

Unfortunately, we can't implement either change (that I can see) with
STL. I don't see any way to support lookup with range-based elements
in any STL data structure.

So here, I implement a skip-list based callset data structure. It
provides optimization (1) above and affords an easy implementation of
(2) as well, (though that is postponed to a later commit).

The skip-list implementation is ported from a C version which Keith
Packard and I implemented for cairo, and with the identical license as
the license of apitrace. The reference I used is the commit named
c2509f8a721ec489e1b44fa8a68be165363787a7 in the cairo repository.

In addition to changing from C to C++, I implemented range-based
elements.


No differences found