说我喜欢这样的课程:
class User
attr_accessor :name, :age
def initialize(name, age)
@name, @age = name, age
end
end
现在,将用户保存为单个文件中的用户类的封送实例或将Sqlite数据库与ORM一起使用会更快吗?基于文件的数据存储有哪些缺点?
答案 0 :(得分:4)
以下是在SSD上执行的基准测试的结果。像你一样解释它们。对于非常简单的查询和数据,将整个数据集编组并加载到内存中的速度更快:
Rehearsal ---------------------------------------------------------------
Storing in DB 0.080000 0.000000 0.080000 ( 0.085909)
Marshalling to Disk 0.010000 0.000000 0.010000 ( 0.004340)
Fetching marshal 0.000000 0.000000 0.000000 ( 0.002288)
Fetching records from DB 5.530000 0.130000 5.660000 ( 5.657053)
Fetching records from Array 0.350000 0.000000 0.350000 ( 0.347798)
Find one record from DB 0.320000 0.020000 0.340000 ( 0.336068)
Find one record from Array 0.260000 0.000000 0.260000 ( 0.258766)
------------------------------------------------------ total: 6.700000sec
user system total real
Storing in DB 0.080000 0.000000 0.080000 ( 0.079717)
Marshalling to Disk 0.000000 0.000000 0.000000 ( 0.002595)
Fetching marshal 0.000000 0.000000 0.000000 ( 0.001466)
Fetching records from DB 10.830000 0.230000 11.060000 ( 11.041669)
Fetching records from Array 0.340000 0.000000 0.340000 ( 0.335473)
Find one record from DB 0.320000 0.010000 0.330000 ( 0.336917)
Find one record from Array 0.260000 0.000000 0.260000 ( 0.255746)
这是基准:
require 'benchmark'
require 'sequel'
class User
attr_reader :name, :age
def initialize(name, age)
@name, @age = name, age
end
def to_hash; {name:@name, age:@age}; end
end
db_array = 1000.times.map{ User.new "name#{rand 1000}", rand(1000) }
db_array << User.new( "unique", 42 )
DBFILE = 'users.db'; MARSHAL = 'users.marshal'
File.delete(DBFILE) if File.exists?(DBFILE)
DB = Sequel.sqlite(DBFILE)
DB.create_table(:users){ column(:name,:string); column(:age,:int) }
db_users = DB[:users]
Benchmark.bmbm do |x|
x.report('Storing in DB'){ db_users.multi_insert db_array.map(&:to_hash) }
x.report('Marshalling to Disk'){ File.open(MARSHAL, 'w'){ |f| f << Marshal.dump(db_array) } }
x.report('Fetching marshal'){ db_array = Marshal.load(File.open(MARSHAL,'r'){|f| f.read }) }
query = db_users.select{ name > "name500" }
x.report('Fetching records from DB'){ 1000.times{ query.all } }
x.report('Fetching records from Array'){ 1000.times{ db_array.select{ |u| u.name > "name500" } } }
x.report('Find one record from DB'){ 1000.times{ db_users[name:'unique'] } }
x.report('Find one record from Array'){ 1000.times{ db_array.find{ |u| u.name == "unique" } } }
end
答案 1 :(得分:3)
存储编组对象的缺点是,您编组的数据可能与以后对ruby类的更改不兼容。因此,您最终可能会将Hash或Array等基本结构保存到文件中。如果您在那时,使用SQLite是更好的选择。
答案 2 :(得分:2)
我认为这取决于你想要做什么操作:如果你只想从文件中读取所有内容,而不执行搜索/选择单个实例和类似的东西,使用文件更好(你只需阅读它和重建实例)。
如果您希望任何类型的访问不同于级联读取,请使用数据库(它们是程序优化的,以尽可能快地写入/读取文件,允许该类型的操作;)
还有另外一个小问题需要考虑:我不知道ruby如何执行和处理文件(因为解析器可能从文件读取速度较慢),我想你可以在ruby论坛上问这个,但我想读一个文件从头到尾都不会有问题
答案 3 :(得分:0)
我会将SQLite与DataMapper ORM(http://datamapper.org/)一起使用。
我认为将用户存储在单个文件中很难管理。使用DataMapper查询SQLite数据库非常简单。