I'm surprised it's only 2-3x times quicker w/Truffle? Is that because it only encodes/decodes a single image at the time and incurs higher startup costs? Or do you mean 2-3x vs. an MRI alternative that calls into a native extension?
I'm curious whether this reflects MRI's improvements closing some of the gap or something else.
I've not got the numbers to hand between versions, but YJIT in Ruby 4.0 did shift the needle a bit, so yes, some gap closing. I also forget what the warmup was like, but to get 2-3x somewhat more was needed than with YJIT.
(Both running identical pure Ruby code, no extensions, in a long-running test scenario, no setup each time.)