2012-08-03 26 views
14

Tenía curiosidad por saber más diferencias entre [] y Array.new y {} y Hash.new¿Diferencias entre literales y constructores? ([] vs Array.new y {} vs Hash.new)

Corrí los mismos puntos de referencia y parece como las abreviaturas son ganadores

require 'benchmark' 

many = 500000 

Benchmark.bm do |b| 
    b.report("[]   \t") {many.times { [].object_id }} 
    b.report("Array.new \t") { many.times { Array.new.object_id }} 
    b.report("{}   \t") {many.times { {}.object_id }} 
    b.report("Hash.new\t") { many.times { Hash.new.object_id }} 
end 


        user  system  total  real 
[]   0.080000 0.000000 0.080000 ( 0.079287) 
Array.new  0.180000 0.000000 0.180000 ( 0.177105) 
{}   0.080000 0.000000 0.080000 ( 0.079467) 
Hash.new  0.260000 0.000000 0.260000 ( 0.264796) 

personalmente me gusta usar de [] la taquigrafía y {}, el código parece tan fresco y fácil de leer.

Cualquier otro puntero ¿cuál es la diferencia entre ellos? ¿Qué sucede detrás de la escena que lo hace tan mejor, y sugerencias si hay alguna cuándo usarlo?

Encontré este link pero estaba buscando obtener más información.

aplausos.

+1

'Hash.new (0)'? –

Respuesta

22

Con Hash.new, puede establecer el valor predeterminado del hash para las claves no configuradas. Esto es bastante útil si está haciendo estadísticas, porque Hash.new(0) le permitirá incrementar las claves sin inicializarlas explícitamente.

+1

+1 para señalar un caso específico común. –

+0

@Robert gracias por especificar un caso de uso, bastante genial – PriteshJ

4

Así que por medio millón de veces todos corrieron "muy rápido". Prefiero los literales en cualquier lenguaje ([], {}, 0, "", etc.) pero los literales no pueden hacer todo (ver documentation para el otro constructor forms). Escribir código limpio, y ser coherente: no hay ningún problema aquí :)

Sin embargo, I sospechosos los literales Evita una búsqueda constante y una llamada al método que se traduce en ellas es más rápido, al menos en ese particular, aplicación .. (alguien con más inteligencia que yo podía mirar a la AST intermedio generado para probar/refutar esto.)

es decir, ¿y si Hash resuelto a una clase personalizada o Hash.new fue sustituida por una método personalizado? No se puede hacer eso con {}. Además, los métodos tienen que tratar con argumentos adicionales (o bloques) mientras que los literales no.

+0

Nunca pensé en este "Hash.new puede reemplazarse con un método personalizado, no se puede hacer eso con {}". buena captura – PriteshJ

+0

@PriteshJ Espero nunca me encuentro con ese código :) –

+0

ya es exactamente pero es genial saber esto, gracias – PriteshJ

2

Robert already mentioned el valor por defecto de la Hash.new

También puede utilizar 'default' valores compley con la variante bloque de Hash.new:

x = Hash.new { |hash, key| 
    hash[key] = key * 2 
} 

p x  #-> {} 
p x[1] #-> 2 
p x  #-> {1=>2} 

Array.new también se puede utilizar para obtener los valores por defecto:

p Array.new(5, :a) #-> [:a, :a, :a, :a, :a] 
Cuestiones relacionadas