More optimization.
More optimization.

- Cache the result of os.path.split(root)[1].lower() (this is *very*
  costly, relatively speaking).
- Cache some more string operations on the Prepared class, and use
  `__slots__` to speed up attribute access.

It would be nice to also use `__slots__` on FastPath, but FastPath
relies on being able to overwrite the joinpath method at the instance
level and that's not compatible with `__slots__`; moving joinpath to
always be on the instance (`self.joinpath = Path(self.root).joinpath`)
is slower due to the sometimes unnecessary creation of a Path instance.

Overall the new version's runtime (on a previously described benchmark)
is around 60% of the original one (i.e. a bit less than 2x speedup).

python/importlib_metadata