I tested the new collections.D function compared to generating random numbers discussed here and here are the results. Test site was generated with hugo new theme test --themesDir . and 1000 pages /content/posts/ added with a bash script. Codes used in both cases in page.html independently–
{{ $t := debug.Timer "TestRandom" }}
{{- $pages := $.CurrentSection.RegularPages }}
{{- range seq 3 }}
{{- with math.Rand | mul $pages.Len | math.Floor | int }}
{{- with collections.Index $pages . }}
<a href="{{ .RelPermalink }}">
<span>{{ with .Parent }}{{ .Title }}{{ else }}{{ .Title }}{{ end }}</span>
<h2>
{{ .Title }}
</h2>
</a>
{{- end}}
{{- end }}
{{- end }}
{{ $t.Stop }}
The results (run 3 times). Public folder deleted after each test.
TestRandom
INFO timer: name TestRandom count 1000 duration 246.01199ms average 246.011µs median 198.349µs
INFO timer: name TestRandom count 1000 duration 231.67484ms average 231.674µs median 212.158µs
INFO timer: name TestRandom count 1000 duration 232.786682ms average 232.786µs median 213.086µs
Collections.D
INFO timer: name TestCollectionsD count 1000 duration 687.046636ms average 687.046µs median 586.14µs
INFO timer: name TestCollectionsD count 1000 duration 715.324944ms average 715.324µs median 606.359µs
INFO timer: name TestCollectionsD count 1000 duration 711.437674ms average 711.437µs median 603.998µs
For comparison, I modified the example site we used in the referenced topic to test collections.D as well:
git clone --single-branch -b hugo-forum-topic-54636 https://github.com/jmooring/hugo-testing hugo-forum-topic-54636
cd hugo-forum-topic-54636
hugo --logLevel info
Result:
TestListRandomPagesMethodD count 10451 duration 1.636667303s average 156.603µs median 116.838µs
TestListRandomPagesMethodA count 10451 duration 3.615900262s average 345.986µs median 294.806µs
TestListRandomPagesMethodB count 10451 duration 5.182145369s average 495.851µs median 408.615µs
TestListRandomPagesMethodC count 10451 duration 12.536497344s average 1.19955ms median 778.693µs
In the results above, TestListRandomPagesMethodD uses the collections.D function, and is much faster than anything else we tried. By comparison, it’s about 8 times faster than using collections.Shuffle (TestListRandomPagesMethodC) in this example.
Note that the Method D implementation in this example uses now.UnixNano as the seed value, so the result of collections.D is very unlikely to be duplicated or cached.
Finally, the list of random pages created by Method D retains the same order as the original page collection. If you want to randomize the order of the list, pass the result through shuffle. Since we’re working with a very small slice the performance impact is neglible.
So the runtime (speed) is one thing. The difference gets even more prominent if you look at the memory allocation stats. There’s some benchmarks that in the Hugo code base that tests the template function:
Error: error building site: render: failed to render pages: render of "/home/tifenak/sites/hugo-forum-topic-54636/content/10-pages/10-pages-01.md" failed: ""/home/tifenak/sites/hugo-forum-topic-54636/layouts/page.html:93:27": execute of template failed: template: page.html:93:27: executing "main" at <now>: wrong type for value; expected int; got int64