Caching

From Inkscape Wiki
Jump to navigation Jump to search

This page is for notes in the discussion on adding caching to Inkscape for a performance boost. It started from a note on caching an item's bounding box (end of Aug 2011).

What to cache

(please write down which object type the data should belong to)

  • SPItem bounding box
    • should invalidate on probably all changes? We could also consider storing a relative bounding box, which stays valid after a translation has been applied. This only works with transforms that scale or translate, not with rotations or shearing. Probably 90% of the time items are merely translated, and not really changed.
  • SPItem snap points
    • should invalidate on all changes of the item, but also on changing snap preferences
  • SPShape conversion to SBasis (2geom path data)
    • should invalidate on path data and transform change
  • SPShape intersections from a path with itself
    • should invalidate on path data and transform change
  • SPLPEItem, LPE intermediate data (related to the input path, this requires some architectural changes in LPE code)
    • invalidates on path data change
  • LivePathEffect::Parameter
    • intermediate results, like arc-length-reparametrisation for LPE-Bend
    • LivePathEffect::PathParam already caches the conversion to pwd2

Perhaps it is best to start implementing this by invalidating the full cache for an object if any change on it is detected?

Cache class

A Cache object class that can be added to objects that need a cache. Each object then has its own cache, so no clashing of itemnames in the cache etc. The item's cache object can be publicly accessible for some classes, and is private in other classes, right? All Cache objects should somehow be monitored for memory use, such that things can be invalidated/removed when Inkscape needs the memory somewhere else.

How about these methods:

  • addValue( string key, any value )
    • adds an item to the cache, could be any type of data (?)
  • bool contains( string key )
    • returns true iff the key is found valid in the cache.
  • retrieve( string key )
    • returns optional value. Must work out how to return "no value found".
  • invalidate( string key )
    • invalidates named entry, or all entries when string is NULL or "all" ?

Code example:

   Geom::Rect bbox;
   if (cache.contains("bbox")) {
       bbox = cache.retrieve("bbox");
   } else {
       bbox = calcbbox(...);
       cache.addValue("bbox", bbox);
   }

Or maybe:

   Geom::Rect bbox = cache.get("bbox", ...); // string key + factory callback
   // cache.get looks for the key-value mapping and decides what to return
   // Advantages:
   // - client code shorter and thus simpler to read
   // - Avoid duplication of code