Well, we’re talking about emulation here, not a bytecode interpreter for a high level dynamically typed language. CPython is fairly slow, it’s written in C in a fairly understandable way, effectively using a large switch statement. There’s like three jumps or so per executed bytecode, it probably uses some jump table.
„All the tricks“ for an interpreter would mean 1 jump per interpreted instruction, or perhaps 0.5 for some of them. It would probably mean no explicit jump tables. It would probably mean the interpreter is set up pipelined like a real cpu - loading instructions on parallel with executing previous instructions. You can get perhaps 5-15% of native speed using for an interpreter all the tricks. QEMU can maybe get 20-50% (not sure these days actually, I haven’t followed improvements for a while). Rosetta can get close to 100%, using a JIT but also hardware that is specifically designed to aid emulation (memory accesses like on x86).
Given nowadays CPUs execute like 3-5 instructions per cycle, getting 5-15% performance for an interpreter would be very fast and very difficult to achieve, but possible - if designed from the ground up for performance.