什么时候应该使用结构与OpenStruct?(When should I use Struct vs

2019-06-17 14:35发布

在一般情况下,有什么比一个结构使用OpenStruct的优势和劣势? 什么类型的一般使用情况将适合每一种?

Answer 1:

随着OpenStruct ,你可以任意创建属性。 一个Struct ,而另一方面,必须在创建它的属性来定义。 一个比其他的选择应该主要基于你是否需要能够在以后添加属性。

想想他们的方式是另一侧散列和类之间的光谱的中间地带。 他们暗示不是做了数据之间更具体的关系Hash ,但他们没有实例方法是将一类。 的一个函数选项的束,例如,使在散感; 他们只是松散的联系。 姓名,电子邮件和电话的功能需要的数量可以在一个封装在一起的StructOpenStruct 。 如果姓名,电子邮件和电话号码所需的方法来提供这两个“第一个最后”和“姓氏,名字”格式的名称,那么你应该创建一个类来处理它。



Answer 2:

其他基准:

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

对于谁想要得到的基准测试结果的想法,不运行他们自己的不耐烦,这里是代码的输出上面(上MB Pro的2.4GHz的酷睿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)


Answer 3:

更新:

随着Ruby 2.4.1的OpenStruct和结构在速度上更接近。 见https://stackoverflow.com/a/43987844/128421

先前:

为了完整: 结构类别哈希OpenStruct

运行相似代码作为burtlo的,关于Ruby 1.9.2,(1 4的芯x86_64的,8GB RAM)[表编辑对齐列]:

creating 1 Mio Structs :         1.43 sec ,  219 MB /  90MB (virt/res)
creating 1 Mio Class instances : 1.43 sec ,  219 MB /  90MB (virt/res)
creating 1 Mio Hashes  :         4.46 sec ,  493 MB / 364MB (virt/res)
creating 1 Mio OpenStructs :   415.13 sec , 2464 MB / 2.3GB (virt/res) # ~100x slower than Hashes
creating 100K OpenStructs :     10.96 sec ,  369 MB / 242MB (virt/res)

OpenStructs是sloooooow内存密集型 ,并没有为大型数据集的规模以及

创建1个神达OpenStructs是〜100倍比创建1个神达哈希

start = Time.now

collection = (1..10**6).collect do |i|
  {:name => "User" , :age => 21}
end; 1

stop = Time.now

puts "#{stop - start} seconds elapsed"


Answer 4:

该用例两者是完全不同的。

你可以认为在Ruby中1.9结构类作为一个相当于的struct中C.声明在Ruby Struct.new采用一组字段名作为参数,并返回一个新的类。 同样,在C,一个struct声明采用一组字段,并允许程序员使用新的复杂类型,就像他对待任何内置类型。

红宝石:

Newtype = Struct.new(:data1, :data2)
n = Newtype.new

C:

typedef struct {
  int data1;
  char data2;
} newtype;

newtype n;

所述OpenStruct类可以与匿名结构声明中C.它允许程序员创建复杂类型的实例

红宝石:

o = OpenStruct.new(data1: 0, data2: 0) 
o.data1 = 1
o.data2 = 2

C:

struct {
  int data1;
  char data2;
} o;

o.data1 = 1;
o.data2 = 2;

下面是一些常见的用例。

OpenStructs可以用来方便地转换哈希向其所有的哈希键响应一次性的对象。

h = { a: 1, b: 2 }
o = OpenStruct.new(h)
o.a = 1
o.b = 2

结构可以为速记类定义是有用的。

class MyClass < Struct.new(:a,:b,:c)
end

m = MyClass.new
m.a = 1


Answer 5:

OpenStructs使用显著更多的内存和速度较慢的表演对的Structs。

require 'ostruct' 

collection = (1..100000).collect do |index|
   OpenStruct.new(:name => "User", :age => 21)
end

在我的系统下面的代码在14秒之执行,消耗1.5 GB的内存。 你可能会因人而异:

User = Struct.new(:name, :age)

collection = (1..100000).collect do |index|
   User.new("User",21)
end

这完成了几乎瞬间和消费的26.6 MB的内存。



Answer 6:

看一看在API方面的新方法。 很多的差异可以在那里找到。

就个人而言,我很喜欢OpenStruct,因为我没有预先定义对象的结构,只是添加的东西,我想。 我想这将是其主要的(DIS)的优势在哪里?

  • http://www.ruby-doc.org/core/classes/Struct.html
  • http://www.ruby-doc.org/stdlib/libdoc/ostruct/rdoc/classes/OpenStruct.html


Answer 7:

Struct

>> s = Struct.new(:a, :b).new(1, 2)
=> #<struct a=1, b=2>
>> s.a
=> 1
>> s.b
=> 2
>> s.c
NoMethodError: undefined method `c` for #<struct a=1, b=2>

OpenStruct

>> require 'ostruct'
=> true
>> os = OpenStruct.new(a: 1, b: 2)
=> #<OpenStruct a=1, b=2>
>> os.a
=> 1
>> os.b
=> 2
>> os.c
=> nil


Answer 8:

使用@Robert代码,我添加HASHIE ::醪基准项目,并得到了这样的结果:

                           user     system      total        real
Hashie::Mash slow      3.600000   0.000000   3.600000 (  3.755142)
Hashie::Mash fast      3.000000   0.000000   3.000000 (  3.318067)
OpenStruct slow       11.200000   0.010000  11.210000 ( 12.095004)
OpenStruct fast       10.900000   0.000000  10.900000 ( 12.669553)
Struct slow            0.370000   0.000000   0.370000 (  0.470550)
Struct fast            0.140000   0.000000   0.140000 (  0.145161)


文章来源: When should I use Struct vs. OpenStruct?
标签: ruby struct