I've been doing some startup and memory benchmarking after the removal
of the deprecated methods (so this is with the master branch, not the
2.12.0 gem release). Benchmarking is a area where even small changes
can have large impacts.
Here's my first approach:
require 'rubygems'
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'sequel'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 1128 6.0 0.9 3008 4444 p0 S+ 2:25PM 0:00.10
ruby sb1.rb
0.319062
billg 1128 6.0 1.9 8012 9556 p0 S+ 2:25PM 0:00.43
ruby sb1.rb
That's weird, I didn't think that Sequel took 5.1MB of RAM by itself
and a third of a second just to start. Turns out the majority of that
is caused by rubygems when you first try to load stuff. I found that
out by modifying the script to include a nonexistant library first and
rescuing the LoadError:
require 'rubygems'
begin
require 'no_such_library'
rescue LoadError
end
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'sequel'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 15585 24.0 1.4 5400 7104 p0 S+ 2:29PM 0:00.31
ruby sb2.rb
0.1454
billg 15585 24.0 1.9 7912 9620 p0 S+ 2:29PM 0:00.48
ruby sb2.rb
2.5MB is certainly better, as is a seventh of a second. I wonder if
we eliminate rubygems entirely:
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/sequel-2.12.0/lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'sequel'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 22416 0.0 0.4 828 2004 p0 S+ 2:33PM 0:00.01
ruby sb3.rb
0.117038
billg 22416 0.0 1.1 4320 5704 p0 S+ 2:33PM 0:00.14
ruby sb3.rb
That drops load time to about a ninth of a second, and while it's
using less RAM in total, it appears that loading Sequel is now taking
more RAM (2.7 MB). What's going on? It turns out that Sequel's
loading of the standard library is what is counted in the addition
memory and speed. Let's try requiring rubygems and using a specific
directory:
require 'rubygems'
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/sequel-2.12.0/lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'sequel'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 16285 0.0 0.9 2808 4440 p0 S+ 2:37PM 0:00.10
ruby sb4.rb
0.095076
billg 16285 0.0 1.2 4596 6248 p0 S+ 2:37PM 0:00.20
ruby sb4.rb
That's better. It starts in less than a tenth of a second, and takes
up only aroud 1.8MB of RAM.
Just for kicks, let's try the same approach with ActiveSupport (not
ActiveRecord, just one of the libraries ActiveRecord requires):
require 'rubygems'
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.2/
lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'active_support'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 4259 0.0 0.9 2832 4432 p0 S+ 2:41PM 0:00.10
ruby sb5.rb
0.498411
billg 4259 43.0 2.2 8984 10956 p0 S+ 2:41PM 0:00.62
ruby sb5.rb
Wow, ActiveSupport by itself takes 5 times longer to load and over 3.5
times more memory. Let's try with ActiveRecord now:
require 'rubygems'
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.2/
lib/')
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/
lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'active_record'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 8654 0.0 0.9 2940 4424 p0 S+ 2:46PM 0:00.10
ruby sb6.rb
0.522444
billg 8654 0.0 2.1 9040 10872 p0 S+ 2:46PM 0:00.64
ruby sb6.rb
That's truly incredible. ActiveRecord only takes an additional 0.024
seconds to start, and uses less RAM that ActiveSupport. I mean, WTF?
Obviously my benchmark sucks, right? I'll leave that open for debate,
but these results are due to the fact that ActiveRecord uses autoload
for pretty much everything. Here's the real story if you are using
all of ActiveRecord:
require 'rubygems'
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.2/
lib/')
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/
lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'active_record'
%w'base.rb aggregations.rb association_preload.rb associations.rb
associations/association_collection.rb associations/
association_proxy.rb associations/belongs_to_association.rb
associations/belongs_to_polymorphic_association.rb associations/
has_and_belongs_to_many_association.rb associations/
has_many_association.rb associations/has_many_through_association.rb
associations/has_one_association.rb associations/
has_one_through_association.rb attribute_methods.rb'.each{|f| require
'active_record/' + f}
%w'autosave_association.rb batches.rb calculations.rb callbacks.rb
dirty.rb dynamic_finder_match.rb dynamic_scope_match.rb fixtures.rb
i18n_interpolation_deprecation.rb locking/optimistic.rb locking/
pessimistic.rb migration.rb named_scope.rb nested_attributes.rb
observer.rb query_cache.rb'.each{|f| require 'active_record/' + f}
%w'reflection.rb schema.rb schema_dumper.rb serialization.rb
serializers/json_serializer.rb serializers/xml_serializer.rb
test_case.rb timestamp.rb transactions.rb validations.rb
version.rb'.each{|f| require 'active_record/' + f}
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 25193 0.0 0.9 3036 4448 p0 S+ 2:49PM 0:00.10
ruby sb7.rb
0.902658
billg 25193 24.0 3.1 13880 15644 p0 S+ 2:49PM 0:01.03
ruby sb7.rb
So using all of ActiveRecord takes about 6 times more memory than
Sequel, and almost 10 times as long to start.
In case any of you are wondering about the difference between all of
Sequel and just core Sequel:
require 'rubygems'
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/sequel-2.12.0/lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'sequel/core'
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 4282 0.0 0.9 2884 4432 p0 S+ 2:51PM 0:00.10
ruby sb8.rb
0.075444
billg 4282 0.0 1.2 4452 6016 p0 S+ 2:51PM 0:00.18
ruby sb8.rb
So using just core Sequel loads about 20% faster and uses 230K less
memory. This just goes to show how lightweight Sequel models are.
Maybe someone will say that this isn't a fair comparison with
ActiveRecord, since some ActiveRecord standard features such as
validation and hook class methods are plugins in Sequel. Let's try
loading all of Sequel's extensions and plugins at once and see how we
compare:
require 'rubygems'
$:.unshift('/usr/local/lib/ruby/gems/1.8/gems/sequel-2.12.0/lib/')
GC.start
system 'ps -ux | fgrep ruby'
t1 = Time.now
require 'sequel'
%w'caching hook_class_methods schema serialization
single_table_inheritance validation_class_methods
validation_helpers'.each{|x| require "sequel/plugins/#{x}"}
%w'blank inflector migration pagination pretty_table query
string_date_time'.each{|x| require "sequel/extensions/#{x}"}
puts Time.now - t1
GC.start
system 'ps -ux | fgrep ruby'
results:
billg 3619 0.0 0.9 2960 4412 p0 S+ 2:59PM 0:00.10
ruby sb9.rb
0.110546
billg 3619 0.0 1.3 4972 6444 p0 S+ 2:59PM 0:00.22
ruby sb9.rb
Looks like all extensions and plugins combined only take up an extra
0.015 seconds and 200KB of RAM.
I mentioned in my presentations that Sequel takes 2-3 times less
memory than ActiveRecord, and starts 2-3 times faster. Turns out I
was much too nice to ActiveRecord. Sequel starts 10 times faster and
uses about 6 times less RAM on startup.
I'm going to be doing some performance and memory benchmarking of
Sequel and ActiveRecord in active use sometime soon using my
simple_orm_benchmark tool. I will be posting the results here.
If you have any questions about these benchmarks, please let me know.
Jeremy
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en
-~----------~----~----~----~------~----~------~--~---