Though, a small amount of assembly and a small understanding of processor design and implementation (I highly recommend MIT 6.004) go a long way into having a better mental model of what Java/JavaScript/C/C++ are actually doing under the covers and what's going on.
I was working on a project where I looked at the Philox4x32 random number generator specification and implemented it in Java. A colleague was trying to speed things up by porting it to C++ and so he just used the liberally licensed reference C++ implementation. He couldn't figure out why my Java implementation was significantly faster than the C++. I had a look, at the C++ implementation, and they missed an optimization to save one register in the inner loop. I didn't disassemble the native binary or have the JVM dissassemble JIT'd code, but I guessed that a register spill (32-bit x86 is pretty register starved) in the inner loop was the problem. Just by applying my optimization, he got the C++ implementation faster than the Java implementation.