Skip to content
  • Federico Mena Quintero's avatar
    PathBuilder: use a SmallVec while the path commands are being accumulated · ee63041d
    Federico Mena Quintero authored
    From the last commit, we had this for the big SVG file in #574:
    
    --------------------------------------------------------------------------------
      n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
    --------------------------------------------------------------------------------
     30 22,796,106,012    1,553,581,072    1,329,943,324   223,637,748            0
                                                           ^^^^^^^^^^^
    
    That extra-heap is a lot of allocator metadata or waste space,
    possibly from heap fragmentation due to all the realloc() shenanigans
    from using into_boxed_slice() on the starting Vec<PathCommand>.
    
    This commit makes PathBuilder use a SmallVec:
    
        pub struct PathBuilder {
            path_commands: SmallVec<[PathCommand; 32]>,
        }
    
    That is, it will keep up to 32 PathCommand directly inside itself, and
    only spill to a heap allocation if more elements come in.
    
    We still into_boxed_slice() for the final Path.  Hopefully this makes
    realloc() find heap blocks that are more closely packed.  Indeed:
    
    --------------------------------------------------------------------------------
      n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
    --------------------------------------------------------------------------------
     33 24,139,598,653    1,416,831,176    1,329,943,212    86,887,964            0
                                                            ^^^^^^^^^^
    
    That's a lot of less waste space.  Note also how the total bytes
    shrinks from 1,553,581,072 to 1,416,831,176.
    ee63041d