更新:
创建 100 万个实例的时间:
0.357788 seconds elapsed for Class.new (Ruby 2.5.5)
0.764953 seconds elapsed for Struct (Ruby 2.5.5)
0.842782 seconds elapsed for Hash (Ruby 2.5.5)
2.211959 seconds elapsed for OpenStruct (Ruby 2.5.5)
0.213175 seconds elapsed for Class.new (Ruby 2.6.3)
0.335341 seconds elapsed for Struct (Ruby 2.6.3)
0.836996 seconds elapsed for Hash (Ruby 2.6.3)
2.070901 seconds elapsed for OpenStruct (Ruby 2.6.3)
0.936016 seconds elapsed for Class.new (Ruby 2.7.2)
0.453067 seconds elapsed for Struct (Ruby 2.7.2)
1.016676 seconds elapsed for Hash (Ruby 2.7.2)
1.482318 seconds elapsed for OpenStruct (Ruby 2.7.2)
0.421272 seconds elapsed for Class.new (Ruby 3.0.0)
0.322617 seconds elapsed for Struct (Ruby 3.0.0)
0.719928 seconds elapsed for Hash (Ruby 3.0.0)
35.130777 seconds elapsed for OpenStruct (Ruby 3.0.0) (oops!)
0.443975 seconds elapsed for Class.new (Ruby 3.0.1)
0.348031 seconds elapsed for Struct (Ruby 3.0.1)
0.737662 seconds elapsed for Hash (Ruby 3.0.1)
16.264204 seconds elapsed for SmartHash (Ruby 3.0.1) (meh)
53.396924 seconds elapsed for OpenStruct (Ruby 3.0.1) (oops!)
请参阅:Ruby 3.0.0 Bug #18032 已关闭,因为它是一项功能,而不是错误
旧答案:
从 Ruby 2.4.1 开始,OpenStruct 和 Struct 在速度上更加接近。见https://stackoverflow.com/a/43987844/128421
为了完整性:Struct vs. Class vs. Hash vs. OpenStruct
在 Ruby 1.9.2 上运行与 burtlo 类似的代码,(4 个内核中的 1 个 x86_64,8GB RAM)[表已编辑以对齐列]:
创建 1 个 Mio 结构:1.43 秒,219 MB / 90MB (virt/res)
创建 1 个 Mio 类实例:1.43 秒,219 MB / 90MB (virt/res)
创建 1 个 Mio 哈希:4.46 秒,493 MB / 364MB (virt/res)
创建 1 个 Mio OpenStructs : 415.13 sec , 2464 MB / 2.3GB (virt/res) # 比哈希慢约 100 倍
创建 100K OpenStructs : 10.96 sec , 369 MB / 242MB (virt/res)
OpenStructs sloooooow 和 内存密集型,并且不能很好地适应大型数据集
这是重现结果的脚本:
require 'ostruct'
require 'smart_hash'
MAX = 1_000_000
class C;
attr_accessor :name, :age;
def initialize(name, age)
self.name = name
self.age = age
end
end
start = Time.now
collection = (1..MAX).collect do |i|
C.new('User', 21)
end; 1
stop = Time.now
puts " #{stop - start} seconds elapsed for Class.new (Ruby #{RUBY_VERSION})"
s = Struct.new(:name, :age)
start = Time.now
collection = (1..MAX).collect do |i|
s.new('User', 21)
end; 1
stop = Time.now
puts " #{stop - start} seconds elapsed for Struct (Ruby #{RUBY_VERSION})"
start = Time.now
collection = (1..MAX).collect do |i|
{:name => "User" , :age => 21}
end; 1
stop = Time.now
puts " #{stop - start} seconds elapsed for Hash (Ruby #{RUBY_VERSION})"
start = Time.now
collection = (1..MAX).collect do |i|
s = SmartHash[].merge( {:name => "User" , :age => 21} )
end; 1
stop = Time.now
puts " #{stop - start} seconds elapsed for SmartHash (Ruby #{RUBY_VERSION})"
start = Time.now
collection = (1..MAX).collect do |i|
OpenStruct.new(:name => "User" , :age => 21)
end; 1
stop = Time.now
puts " #{stop - start} seconds elapsed for OpenStruct (Ruby #{RUBY_VERSION})"