No post passado eu falei sobre os benefícios do Rails 2.2 em termos de performance que obtive na minha aplicação. Porém, não deixei bem claro que a intenção dos meus testes eram comparar a diferença entre as duas versões do Rails apenas, sem tocar no interpretador Ruby. Então pra deixar as coisas mais claras, vou analizar aqui as diferenças entre os interpretadores Ruby 1.8 (MRI), Ruby 1.9 (YARV) e JRuby (JVM).

Ruby 1.8

É o Ruby estável atual. Suporta apenas Green Threads.
Isso significa que, não importa quantas threads você rode no seu programa, haverá apenas uma Thread alocada no kernel do sistema operacional. O efeito colateral disso é a necessidade de esperar que uma Thread termine a sua execução para começar outra Thread.
Até pouco tempo a solução para esse problema eram clusters de servidores. Com vários servidores rodando, cada um fica responsável por uma requisição, permitindo a execução de mais de um processo ao mesmo tempo (não concorrente). Mas gerava um outro problema: cada servidor precisava carregar na memória todas as bibliotecas, classes do framework, classes da aplicação, etc, o que gera um overload de memória.
Então chegaram os Phusion Guys com o Passenger e o Ruby Enterprise Edition, que juntos otimizaram esse processo. O que o Ruby Enterprise Edition fez foi compartilhar os objetos iguais entre as instâncias de Rails, diminuindo o overload. Contúdo você ainda tem conexões de banco, código de aplicação e dados em memória criados depois da inicialização duplicados.

Ruby 1.9

O Ruby 1.9 implementa o YARV (desenvolvido pelo Matz assim como o MRI) como virtual machine, o qual suporta Native Threads. Isso significa que cada Thread Ruby terá sua própria Thread no kernel do sistema operacional. Porém, isso não significa que haverá paralelismo entre as execuções das Threads. Somente um processo rodará por vez, independente de quantos cores tenha o servidor. Isso acontece devido ao GIL (Global Interpreter Lock), que também está presente no MRI.
O GIL nada mais é que uma trava gerada quando são solicitados processos de IO, para impedir que seja compartilhado código que não é Thread Safe entre as Threads.
Remover o GIL beneficiaria a utilização de mais de 1 core no servidor, pois possibilitaria a execução paralela de Threads. O problema é que muitas extensões feitas em C precisariam ser reescritas, o que atrasaria o lançamento. Talvez isso esteja nos planos para a versão 2.0.

JRuby

O JRuby usa JVM, a máquina virtual Java, e que suporta Native Threads e execução simultânea.
Isso significa dizer que várias requisições poderão ser executadas paralelamente, dependendo únicamente da quantidade de cores do seu servidor.

Então por que houve melhora na performance sem trocar o interpretador?

O que acontecia com o Rails até a versão 2.1.1 é que havia um lock único sobre cada requisição, e que fora substituido na versão 2.2 por locks menores, sobre os recursos compartilhados apenas. Porém, ao meu ver, mais importante que isso para a melhora de performance é o pool de conexões. Na versão 2.2, você pode configurar um pool de conexões com o banco de dados que serão acessados ao mesmo tempo.
No seu blog o Carlos Brando explicou como o pool de conexões funciona. Vale o acesso.