Before OTP24:
BEAM does not have JIT, so typically the erlang compiler (erlc) outputs bytecode: Any math operation needs to access the VM registers (which are memory positions), perform the actual operation, place the result in the relevant VM register and then jump to the next instruction. This is quite slow compared to just performing the actual operation in machine code.
If you use any language that compiles directly to machine code (like C), the compiler has a lot more information about the code and the platform and thus is able to use features that speed up execution of the operations like optimizing the processor's pipeline, using vectorized instructions, placing the most accessed variables in processor's registers, optimizing memory access so that they hit the cache...
The HiPE compiler is there to compile erlang code to native, and you should use it if your program uses a lot of math. Be sure to check its limitations, though.
If the HiPE compiler is not enough, you can always code the critical math operations in C and include it.
Furthermore, you should check this question with a comparison between Erlang and C (and others) for a pure math problem
Regarding immutability, it shouldn't have any impact unless your integers are placed on the thread's heap (>60bits) because those are the only ones that require explicit memory handling.
In order to profile Erlang code, you have these tools to deal with Erlang from within.
Lastly, you can always post your snippet here and maybe we'll be able to point something.
After OTP24:
Erlang now has JIT, some reports state as much as 25% improvement.