En général, quels sont les avantages et les inconvénients de l'utilisation d'un OpenStruct par rapport à une Structure? Ce type de l'utilisation générale des cas, correspondent à chacun de ces?
Réponses
Trop de publicités?Avec un OpenStruct, vous pouvez créer artificiellement des attributs. Une Structure, d'autre part, doit avoir ses attributs définis lors de sa création. Le choix de l'un sur l'autre devrait être fondée principalement sur si vous devez être en mesure d'ajouter des attributs plus tard.
La façon de penser est que le milieu de terrain du spectre entre les Hachages d'un côté et des cours sur l'autre. Ils impliquent une plus concrète de la relation entre les données de Hachage, mais ils n'ont pas les méthodes d'instance comme le ferait une classe. Un tas d'options pour une fonction, par exemple, a de sens que dans une table de hachage; ils ne sont que vaguement liés. Un nom, courriel et numéro de téléphone requis par une fonction pourrait être emballés ensemble dans une Structure ou OpenStruct. Si ce nom, courriel et numéro de téléphone requis méthodes pour fournir le nom dans les deux "prénom" et "nom, prénom" formats, vous devez créer une classe permettant de gérer.
Autre indice:
require 'benchmark'
require 'ostruct'
REP = 100000
User = Struct.new(:name, :age)
USER = "User".freeze
AGE = 21
HASH = {:name => USER, :age => AGE}.freeze
Benchmark.bm 20 do |x|
x.report 'OpenStruct slow' do
REP.times do |index|
OpenStruct.new(:name => "User", :age => 21)
end
end
x.report 'OpenStruct fast' do
REP.times do |index|
OpenStruct.new(HASH)
end
end
x.report 'Struct slow' do
REP.times do |index|
User.new("User", 21)
end
end
x.report 'Struct fast' do
REP.times do |index|
User.new(USER, AGE)
end
end
end
Pour les impatients qui veut avoir une idée de l'indice de référence des résultats, sans les exécuter eux-mêmes, ici, c'est la sortie du code ci-dessus (sur un MB Pro 2.4 GHz i7)
user system total real
OpenStruct slow 4.430000 0.250000 4.680000 ( 4.683851)
OpenStruct fast 4.380000 0.270000 4.650000 ( 4.649809)
Struct slow 0.090000 0.000000 0.090000 ( 0.094136)
Struct fast 0.080000 0.000000 0.080000 ( 0.078940)
Pour être complet: Struct vs Hachage vs OpenStruct vs Classe
L'exécution de code similaire comme burtlo, sur Ruby 1.9.2, (1 des 4 cœurs x86_64, 8 go de RAM):
la création de 1 Mio Structures : 1.43 sec , 219MB / 90 MO (virt/res) la création de 1 Mio instances de Classe : 1.43 sec , 219MB / 90 MO (virt/res) la création de 1 Mio de Hachages : 4.46 sec , 493 MO / 364MB (virt/res) la création de 1 Mio OpenStructs : 415.13 sec , 2464 MO / 2.3 GO (virt/res) # ~100 fois plus lent que les Hachages la création de 100K OpenStructs : 10.96 sec , 369 MO , 242 MO (virt/res)
OpenStructs sont sloooooow et les plus gourmands en mémoire , et n'est pas à l'échelle de grands ensembles de données
La création de 1 Mio OpenStructs est de ~100 fois plus lent que la création de 1 Mio de Hachages.
start = Time.now
collection = (1..10**6).collect do |i|
{:name => "User" , :age => 21}
end; 1
stop = Time.now
puts "#{stop - start} seconds elapsed"
J'ai quelques remarques à propos de Struct vs OpenStruct vs Hachage dans mon récent commentaire de blog "les Structures à l'intérieur", juste au cas où quelqu'un est intéressé.
OpenStructs utiliser beaucoup plus de mémoire et sont plus lents artistes interprètes ou exécutants contre des Structures.
require 'ostruct'
collection = (1..100000).collect do |index|
OpenStruct.new(:name => "User", :age => 21)
end
Sur mon système, le code suivant exécuté en 14 secondes et consommé 1,5 GO de mémoire. Votre kilométrage peut varier:
User = Struct.new(:name, :age)
collection = (1..100000).collect do |index|
User.new("User",21)
end
Qui fini presque instantanément et consommé de 26,6 MO de mémoire.