By
* Caching common sites matrix setups (e.g. the single site in single site setups).
* Adding a fast path to IntSets.HasAnyVector for the common case of single vector input.
```
AssembleDeepSiteWithManySections/depth=3/sectionsPerLevel=2/pagesPerSection=100-10 31.62m ± 46% 30.68m ± 42% ~ (p=0.310 n=6)
│ master.bench │ perfcommon.bench │
│ B/op │ B/op vs base │
AssembleDeepSiteWithManySections/depth=3/sectionsPerLevel=2/pagesPerSection=100-10 31.98Mi ± 0% 31.24Mi ± 0% -2.30% (p=0.002 n=6)
│ master.bench │ perfcommon.bench │
│ allocs/op │ allocs/op vs base │
AssembleDeepSiteWithManySections/depth=3/sectionsPerLevel=2/pagesPerSection=100-10 460.9k ± 0% 419.9k ± 0% -8.90% (p=0.002 n=6)
````
Hugo's build process is roughly divided into three steps:
1. Process content (walk file system and insert source nodes into content tree)
2. Assemble content (assemble pages and resources according to sites matrix)
3. Render content
In #13679 we consolidated the page creation logic into one place (the assemble step). This made it much simpler to reason about, but it lost us some performance esp. in big content trees.
This commit re-introduces parallelization in the first step in the assemble step by handling each top level section in its own goroutine. This gives significant performance improvements for content trees with many sections.
Compared to master:
```
AssembleDeepSiteWithManySections/depth=1/sectionsPerLevel=6/pagesPerSection=100-10 19.26m ± ∞ ¹ 14.54m ± ∞ ¹ -24.52% (p=0.029 n=4)
AssembleDeepSiteWithManySections/depth=2/sectionsPerLevel=2/pagesPerSection=100-10 19.74m ± ∞ ¹ 16.45m ± ∞ ¹ -16.71% (p=0.029 n=4)
AssembleDeepSiteWithManySections/depth=2/sectionsPerLevel=6/pagesPerSection=100-10 106.18m ± ∞ ¹ 71.23m ± ∞ ¹ -32.91% (p=0.029 n=4)
AssembleDeepSiteWithManySections/depth=3/sectionsPerLevel=2/pagesPerSection=100-10 38.85m ± ∞ ¹ 30.47m ± ∞ ¹ -21.59% (p=0.029 n=4)
```
We already cached the method index on the struct, but caching the resolved `reflect.Method` itself saves us from having to do another lookup on each call, which is escpeciall import in the hot path used by collections.Where and otherrs:
```bash
│ master.bench │ fix-reflectmethodcache.bench │
│ sec/op │ sec/op vs base │
WhereSliceOfStructPointersWithMethod-10 592.2µ ± ∞ ¹ 390.1µ ± ∞ ¹ -34.14% (p=0.029 n=4)
¹ need >= 6 samples for confidence interval at level 0.95
│ master.bench │ fix-reflectmethodcache.bench │
│ B/op │ B/op vs base │
WhereSliceOfStructPointersWithMethod-10 205.14Ki ± ∞ ¹ 64.52Ki ± ∞ ¹ -68.55% (p=0.029 n=4)
¹ need >= 6 samples for confidence interval at level 0.95
│ master.bench │ fix-reflectmethodcache.bench │
│ allocs/op │ allocs/op vs base │
WhereSliceOfStructPointersWithMethod-10 9.003k ± ∞ ¹ 4.503k ± ∞ ¹ -49.98% (p=0.029 n=4)
````
* Use helper funcs in hreflect package when possible.
* Use hreflect.ConvertIfPossible to handle conversions when possible.
* Move scratch.go from common/maps to common/hstore to clear cyclic import in the next step.
* Move Indirect to hreflect and reimplementing it and adusting the behavior to preserve struct pointers.
* Adjust evaluateSubElem used by where and others making the struct pointer method case slightly faster.
E.g. in date.AddDate.
In Hugo v0.152.0 we moved to a new YAML library (github.com/goccy/go-yaml) which produces uint64 for unsigned integers.
This unfortunately breaks common constructs like:
.Date.AddDate 0 0 7
when .Date is a time.Time and the integers are unmarshaled from YAML front matter.
This commit adds code to handle conversion from uint64 (and other int types) to the required int types where possible.
Fixes#14079