For the full gmpy2 port python ints that set initial values, like that of R >>104, are converted to mpz, while those in running computations are subject to implicit conversion >>139. Divisions with powers of 2 are replaced with t_div_2exp and the rest with divexact.
https://gmpy2.readthedocs.io/en/latest/mpz.html#mpz-functions
$ python3 -m timeit -s 'import numsci.hofs as mod' 'mod.work_gmp ('"1$(printf "%078d" 0)"')'
10 loops, best of 3: 4.18 sec per loop
The time for R(10^78) drops from 4.8s >>105 to 4.2s, so one eighth of the runtime is shaved off. Not as much as I had hoped but an improvement nevertheless.
$ python3 -m cProfile -s time wrapper.py numsci.hofs gmp "1$(printf "%078d" 0)" | tee temp/profile.txt | less
levels: 5
1000000000000000000000000000000000000000000000000000000000000000000000000000000 -> 500000000000000000000000000000000000000942809041582063365839428238027648024522282176747574937498915190189902751724515553262387695706471431607983773634306949 0x254AAD173EA5E82CB765169D1EFC9860FE05AE7B1E8FB19314D597561CED1F19F448CA74BCDEE10F0F168DAE0F529DA97AADE66B397A970EDCFEA83CA35C68A385 518
2584205 function calls (2583609 primitive calls) in 4.811 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
143277 3.488 0.000 3.527 0.000 hofs.py:590(increment)
143296 0.304 0.000 0.351 0.000 hofs.py:560(increment)
1 0.192 0.192 4.798 4.798 hofs.py:909(work_layers_loop)
143397 0.153 0.000 0.913 0.000 hofs.py:869(counts)
143331 0.142 0.000 0.175 0.000 hofs.py:535(increment)
143828/143279 0.100 0.000 0.113 0.000 hofs.py:446(gmp_next)
429904 0.080 0.000 0.080 0.000 {built-in method gmpy2.divexact}
Perhaps the GMP port will yield a nicer speed boost.