Hice algunos puntos de referencia rápidos y sucios en algunas de las respuestas dadas. (Es posible que estos hallazgos no sean exactamente idénticos a los suyos según la versión de Ruby, almacenamiento en caché extraño, etc., pero los resultados generales serán similares).
arr
es una colección de objetos ActiveRecord.
Benchmark.measure {
100000.times {
Hash[arr.map{ |a| [a.id, a] }]
}
}
Benchmark @ real = 0.860651, @ cstime = 0.0, @ cutime = 0.0, @ stime = 0.0, @ utime = 0.8500000000000005, @ total = 0.8500000000000005
Benchmark.measure {
100000.times {
h = Hash[arr.collect { |v| [v.id, v] }]
}
}
Benchmark @ real = 0.74612, @ cstime = 0.0, @ cutime = 0.0, @ stime = 0.010000000000000009, @ utime = 0.740000000000002, @ total = 0.750000000000002
Benchmark.measure {
100000.times {
hash = {}
arr.each { |a| hash[a.id] = a }
}
}
Benchmark @ real = 0.627355, @ cstime = 0.0, @ cutime = 0.0, @ stime = 0.010000000000000009, @ utime = 0.6199999999999974, @ total = 0.6299999999999975
Benchmark.measure {
100000.times {
arr.each_with_object({}) { |v, h| h[v.id] = v }
}
}
Benchmark @ real = 1.650568, @ cstime = 0.0, @ cutime = 0.0, @ stime = 0.12999999999999998, @ utime = 1.51, @ total = 1.64
En conclusión
El hecho de que Ruby sea expresiva y dinámica no significa que siempre debas buscar la solución más bonita. El básico de cada ciclo fue el más rápido en la creación de un hash.
... { |v| [v, f(v)] }
, ¡pero esto funcionó!