Hi Jeremy

I was able to fetch a bit more information on the subject.

First of all, memprof back-end processing seems to be not working
right, my uploaded data got stuck there in their processing queue.
Still, data I was able to get from it locally was very valuable.

I found that replacing 'model-centric' query with 'table-centric'
query saved me about 40kb per query. Does not seem like much, but with
5 of those queries per request and 500 request in a row this change
alone reduced 'short-lived objects' total size from 600MB to 500MB.

Old query:

          Sequel::Channel.
            eager_graph(:subscriptions).
            filter(:subscriptions__user_id => :$user_id).
            select(:channels__id).
            order(:id).
            ungraphed

New query:

          SDB[:users].
            join(:subscriptions, :user_id => :id).
            filter(:users__id => :$user_id).
            select(:subscriptions__channel_id___id).
            order(:id)

Still, this query seems to create lots of strings and hashes in
memory. It turned out that postgres driver returns back rows as hashes
(sure this is not a surprise to you, Jeremy). Therefore, for each row
it creates new Hash object (waste in this degenerate case of one
column per row), and this Hash object contains key-value pairs as
field-name-to-field-value. Field name is a string, and therefore is
repeated for each and every row, generating more wasted memory.

Replacing Sequel query with

        pg = ActiveRecord::Base.connection.execute("select channel_id
from subscriptions where user_id = #{self.id} order by channel_id")
        rtn.concat(pg.column_values(0).map { |n| Integer(n) })

resulted in 80kb decrease of waste per request (for one query change).
If I do that for all 5 queries, for 500 requests that is 200MB less
waste, bringing me from 500MB to 300MB.

But of course, this code is @#$ ugly. Which leads me to the following
question. Is it possible to use Sequel for query generation/
preparation/execution but... not have it parse the results and instead
hand me back PGresult object?
This would be an almost palatable compromise...

And BTW - quickly running memprof on some of the old ActiveRecord code
suggested that generic ActiveRecord-centric code is much more
wasteful, and that pretty much makes sense... but I do not know how to
explain initial better GC results for ActiveRecord-centric version of
the code. Still there is a mystery here to uncover.

And, in case you are curious, here is a top section of memprof stats
for my whole action (as you can see, it is mostly sequel with
exception of YAJL json generator and some other small chunks).

     48 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/gems/yajl-
ruby-1.1.0/lib/yajl.rb:72:String
     39 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/model/associations.rb:2095:Array
     36 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/adapters/postgres.rb:468:String
     33 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/model/associations.rb:2085:Array
     25 /Users/bar/.rvm/rubies/ruby-1.8.7-p352/lib/ruby/1.8/webrick/
httpserver.rb:55:Array
     24 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/model/associations.rb:2189:Array
     24 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/actions.rb:705:String
     22 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/adapters/postgres.rb:468:Hash
     21 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/model/associations.rb:2202:Array
     19 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/misc.rb:128:String
     16 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/query.rb:55:Class
     16 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/prepared_statements.rb:201:Hash
     16 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/actions.rb:664:Hash
     16 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/adapters/postgres.rb:540:Hash
     16 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/adapters/postgres.rb:428:__scope__
     15 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/adapters/postgres.rb:428:String
     14 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/model/associations.rb:2196:Array
     14 /Users/bar/.rvm/rubies/ruby-1.8.7-p352/lib/ruby/1.8/webrick/
httpserver.rb:55:__node__
     12 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/model/associations.rb:2196:String
     12 /Volumes/Foo/src/proj/app/models/sequel/user.rb:54:__varmap__
     11 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/gems/
actionpack-3.0.10/lib/action_view/lookup_context.rb:119:String
      9 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/gems/
actionpack-3.0.10/lib/action_view/lookup_context.rb:120:Array
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/gems/
sequel_pg-1.2.0/lib/sequel_pg/sequel_pg.rb:49:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/query.rb:57:__node__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/query.rb:57:Array
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/query.rb:56:Hash
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/query.rb:
55:Sequel::Postgres::Dataset
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/prepared_statements.rb:
26:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/prepared_statements.rb:
125:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/actions.rb:664:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/actions.rb:55:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/actions.rb:54:Array
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/dataset/actions.rb:127:Proc
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/database/query.rb:54:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/database/query.rb:54:Array
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/database/connecting.rb:225:__scope__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/database/connecting.rb:224:Proc
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/connection_pool/single.rb:22:__varmap__
      8 /Volumes/Foo/src/proj/vendor/bundle/ruby/1.8/bundler/gems/
sequel-47e347167fd9/lib/sequel/adapters/shared/postgres.rb:
699:__scope__
......

-- 
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.

Reply via email to