Judging from the generated assembly, the OCaml compiler is not able to unbox the float (for the return value) across the recursive call. You can see the subq $16, %r15 cmpq (%r14), %r15
allocation sequence, as well as memory writes inside of the loop of camlExample__calc_5
.
An imperative version does quite a bit better (1.235 vs 2.273 on my machine).