Emulation in advance CPU Vs Native CPU
Several problems here:

1) Speed of light and Causality

A significant part of modern CPU performance comes from stuff like pipelining and branch prediction. For example it may take 4 cycles to execute one addition, but if the pipeline has 4 stages, it can still execute one addition per cycle, which multiplies throughput by 4. Great!

...Unless the next operation reuses the result of the previous one. Then causality dictates the next operation must wait for the result of the previous one to be available, which introduces pipeline stalls.

The most problematic case of this is conditional branches. The CPU does not know if it has to branch or not until the condition has been calculated, so it has to wait. More pipeline stalls. 

An interpreter for any interpreted language needs to ... interpret ... the bytecode which will usually lead to lots of conditionals, switch-case statements, jump tables, etc. This is the worst possible code for any modern CPU which uses branch prediction because the same interpreter inner loop will interpret a different operation every time it is run, so the branch prediction will be wrong most of the time!

Additionally, if the interpreter does not fit into the cpu instruction cache, then it is reeeeally going to suck, because a lot of these mispredicted branches will turn into cache misses and non-prefetched random SDRAM accesses which are slow as hell.

Take-home point: modern pipelined superscalar CPUs are very good at data flow code (apply the same operation many times to lots of data), and terrible at control flow code (lots of tests, jumps, conditions, etc). The latter is a very hard problem, because the performance bottleneck is basically causality and the speed of light (propagation speed of signals), and that's not negotiable.

This is why most CPU emulators recompile the original asm code into the destination cpu asm code... Even if the recompilation is done in a suboptimal way it will still be much better.

Nowadays we'd use LLVM for that. But this is a problem for emulators designed before LLVM...

2) Custom hardware

PS1 has a GPU which does polygon texturing, sprites and geometry, and a sound chip. These are programmable custom hardware.

Emulating custom hardware is usually slow, in part because concurrent hardware processes do not map well to sequential software processes. For example hardware can quickly evaluate lots of flags, bits, compute bitwise operations with a bunch of logic gates, etc. Whereas software will have to run lots of tests and conditions, which brings us back to the point 1) above. Worst case, software has to emulate every logic gate one at a time and this will really suck.

Also the geometry processor uses a non-standard fixed point format that is what you'd expect for optimized custom hardware of the era, and that a modern CPU cannot process without lots of bit-twiddling and contorsions... So you'll get code for "if the sign bit is 1 then..." making your math 10x slower (at least) and this cannot be translated into asm code for your CPU since it manipulates data formats that your CPU does not understand.

And all this stuff runs in parallel, synchronized by electrical signals that will have to be emulated too!

3) Memory

PS1 has RAM for the CPU, another RAM bank for the GPU, another for the sound chip, and each have various internal caches.

Even if clock frequency is low, all that stuff can be accessed in parallel at the same time... with potentially lots of random accesses... and while modern DDR SDRAM is pretty good at sequential throughput, it still sucks, and will always suck at random accesses because of... you guessed it, speed of light. Commands have to go from the cpu, through a controller, to the SDRAM chips, be processed, come back... therefore, latency.

So I wouldn't be surprised if the main performance bottleneck in your emulator was memory, in other words, cache size.