Sqlite vs file-based storage?

Say I have a class like this:

class User
  attr_accessor :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end
end

Now, would it be faster to save users as marshaled instances of the User class in separate files or use the Sqlite database with ORM? What are the disadvantages of file-based data storage?

+3
source share
4 answers

Below are the results of a test performed on an SSD. Interpret them the way you do. For very simple queries and data, sorting and loading the entire data set into memory appears faster:

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)

Here's the benchmark:

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
+4
source

, ruby. , , , , Hash Array, . , SQLite.

+3

, , : , / , ( rebuild ).

, - , ( / , , ;))

: , Ruby (, - ), , ruby, ,

+2
source

I would use SQLite with ORM DataMapper ( http://datamapper.org/ ).

I think that keeping users in a separate file will be difficult. Querying a SQLite database using DataMapper is very simple.

0
source

All Articles