Addendum 1: Benchmarking a single, deep transduction

Construct hashmap of eighteen mathematical ops, per element

Do Brokvolli's transduce benchmarks change with a heavier per-element task?

Observations: The multi-threaded variants' performance improvements increase when the tasks are heavier.

See also:

We'll define our benchmarks here. For each of these functions,

We'll test vectors increasing in length from one element to one-hundred-thousand elements, by powers of ten. For each element, a pre-generated random floating point number, we'll construct a hashmap of eighteen mathematical operations on that number (trig ops, logarithms, etc.) that the JVM compiler oughtn't be able to optimize. We'll use the Criterium benchmarking library to measure the execution times of sixty repetitions of each condition. Benchmarks were run on three explicitly-pinned cores of my geriatric desktop computer.

Overall, we observe that the execution times increase with increasing vector lengths. The results are indistinguishable when the vector contains one-hundred or fewer elements. When the vectors grow longer, the three multi-threaded variants (fold, multi/transduce, and multi/transduce‑kv), offer improvements that scale roughly with the number of processors. The single-threaded functions all perform very similarly. Not surprising, since they all ultimately delegate to the same underlying implementation, reduce/reduce-kv. Unfortunately, my computer was not capable of handling one-million element vectors and I was compelled to stop measuring at one-hundred-thousand elements.

As with the previous benchmarks, the multi-threaded functions appear to offer performance benefits over their single-threaded counterparts for large collection sizes and heavy per-element operations. For smaller collections or shallow transformer stacks, the single-threaded variants perform better, and present a simpler interface.

Construct hashmap of eighteen mathematical ops, per element

This test performs multiple mathematical operations per element, sine, square-root, logarithm, etc.

Execution times increase with vector length. The single- and multi-threaded functions are indistinguishable for one-hundred elements or fewer. When the vectors grow larger than that, the multi-threaded variants demonstrate faster execution (i.e., lower times), roughly by a factor of two.

(fn [n] ((tactics-1 (project-version-lein)) (vecs n)))

Benchmark measurements for expression `(fn [n] ((tactics-1 (project-version-lein)) (vecs n)))`, time versus 'n' arguments, comparing different versions.