Are you able to share the code? It would be easier this way to say something sensible about it.
But from my own experience it’s quite difficult to measure between 2 platforms in a correct way.
(I’m using rustler myself and performance seems to be faster on the 100% rust side, I have never seen the elixir/NIF part being faster because of the (sometimes little) overhead crossing the NIF bridge)
Is it a normal or a dirty NIF? If it is dirty then is the workload IO or CPU bound and is the appropriate flag used in NIF declaration? If It is dirty then does Beam have enough dirty threads set in config (the defaults are rather low)
As @rjk and @yurko said, it can depend on many things. If you could provide MCVE so we could check this out, then maybe we could give you more correct answer.
20’000 iterations in 20 seconds mean less throughput than 2’000 iterations in 1 second. And from what I see Google Bench gives you amount of iterations, not IPS.