Tengo el siguiente método que escribí para Project Euler - Problem 36. Todo lo que hace es sumar todos los números menos de 1.000.000 que son palíndromos, tanto en la base 10 y la base 2.¿La asignación variable es realmente cara en Ruby, o optimiza los métodos de cadena encadenada?
def problem_36
(1...1_000_000).select do |n|
n.to_s == n.to_s.reverse && n.to_s(2) == n.to_s(2).reverse
end
end
Ahora, esto funciona y da el resultado correcto en poco más de 1 segundo. Quería que fuera menos de 1 segundo, así que decidí reducir la cantidad de veces que convertía números a cadenas. Así que hice los siguientes cambios:
def problem_36
(1...1_000_000).select do |n|
base10 = n.to_s
base2 = n.to_s(2)
base10 == base10.reverse && base2 == base2.reverse
end
end
El problema es que esta versión realmente ejecuta alrededor del 50% más lenta que el original. Entonces, la pregunta es: ¿es realmente tan lento asignar esas dos variables? ¿O está Ruby optimizando las llamadas al método encadenado?
Y solo para aclarar, no había una necesidad real de hacer la primera versión más rápido, solo quería ver si podía. Eso solo me hizo tropezar con esta aparente rareza. –
Echa un vistazo a los [resultados en ideone.com] (http://ideone.com/4Seut) –
Mi sospecha: La diferencia está en cómo el recolector de basura maneja objetos temporales sin nombre frente a objetos almacenados en variables. – Chuck