Permalink
Browse files

Three performance improvements:

* for simple cases like User.last and User.order('name desc').last no need to perform Array#join operation.

* Instead of performing String#blank? do Array#empty?

* no need to create variable relation
  • Loading branch information...
Neeraj Singh authored and tenderlove committed Sep 9, 2010
1 parent e3d6434 commit fbd1d306b95cc2efb6422e12d26d5818a3a42343
Showing with 9 additions and 10 deletions.
  1. +9 −10 activerecord/lib/active_record/relation/query_methods.rb
@@ -135,14 +135,13 @@ def extending(*modules, &block)
end
def reverse_order
- order_clause = arel.order_clauses.join(', ')
- relation = except(:order)
+ order_clause = arel.order_clauses
- order = order_clause.blank? ?
+ order = order_clause.empty? ?
"#{@klass.table_name}.#{@klass.primary_key} DESC" :
- reverse_sql_order(order_clause)
+ reverse_sql_order(order_clause).join(', ')
- relation.order(Arel::SqlLiteral.new(order))
+ except(:order).order(Arel::SqlLiteral.new(order))
end
def arel
@@ -283,15 +282,15 @@ def apply_modules(modules)
end
def reverse_sql_order(order_query)
- order_query.split(',').each { |s|
+ order_query.join(', ').split(',').collect { |s|
if s.match(/\s(asc|ASC)$/)
- s.gsub!(/\s(asc|ASC)$/, ' DESC')
+ s.gsub(/\s(asc|ASC)$/, ' DESC')
elsif s.match(/\s(desc|DESC)$/)
- s.gsub!(/\s(desc|DESC)$/, ' ASC')
+ s.gsub(/\s(desc|DESC)$/, ' ASC')
else
- s.concat(' DESC')
+ s + ' DESC'
end
- }.join(',')
+ }
end
def array_of_strings?(o)

12 comments on commit fbd1d30

@carlosantoniodasilva

This comment has been minimized.

Show comment Hide comment
@carlosantoniodasilva

carlosantoniodasilva Sep 27, 2010

Member

Just a question, why removing gsub! and concat in reverse_sql_order?

Just a question, why removing gsub! and concat in reverse_sql_order?

@neerajdotname

This comment has been minimized.

Show comment Hide comment
@neerajdotname

neerajdotname Sep 27, 2010

Member

so that code like "created_at, updated_at" works with User.last. Note that the whole thing is a string. Hence we need to split by a comma.

Member

neerajdotname replied Sep 27, 2010

so that code like "created_at, updated_at" works with User.last. Note that the whole thing is a string. Hence we need to split by a comma.

@carlosantoniodasilva

This comment has been minimized.

Show comment Hide comment
@carlosantoniodasilva

carlosantoniodasilva Sep 27, 2010

Member

Yeah sure Neeraj, but I believe it'd be possible to return the s variable inside the collect, keeping the methods that changes the actual string, would not?

Yeah sure Neeraj, but I believe it'd be possible to return the s variable inside the collect, keeping the methods that changes the actual string, would not?

@neerajdotname

This comment has been minimized.

Show comment Hide comment
@neerajdotname

neerajdotname Sep 27, 2010

Member

Not sure if I am following you exactly. Can you post a gist or something?

Member

neerajdotname replied Sep 27, 2010

Not sure if I am following you exactly. Can you post a gist or something?

@carlosantoniodasilva

This comment has been minimized.

Show comment Hide comment
@carlosantoniodasilva

carlosantoniodasilva Sep 27, 2010

Member

Sure, here we go: http://gist.github.com/599566.
I also thought about some other possibilities to see what you think (didn't actually tested it), please take a look.

Sure, here we go: http://gist.github.com/599566.
I also thought about some other possibilities to see what you think (didn't actually tested it), please take a look.

@thedarkone

This comment has been minimized.

Show comment Hide comment
@thedarkone

thedarkone Sep 27, 2010

Contributor

How about doing "Lazy gsub!": http://gist.github.com/599605?

Contributor

thedarkone replied Sep 27, 2010

How about doing "Lazy gsub!": http://gist.github.com/599605?

@neerajdotname

This comment has been minimized.

Show comment Hide comment
@neerajdotname

neerajdotname Sep 27, 2010

Member

I think I like the "lazy gsub!" . In all other cases first a regex check is being done and then gsub is being invoked. The "lazy gsub!" totally removes the need to do any regex check.

Member

neerajdotname replied Sep 27, 2010

I think I like the "lazy gsub!" . In all other cases first a regex check is being done and then gsub is being invoked. The "lazy gsub!" totally removes the need to do any regex check.

@carlosantoniodasilva

This comment has been minimized.

Show comment Hide comment
@carlosantoniodasilva

carlosantoniodasilva Sep 27, 2010

Member

Yeah agreed, nice one!

Yeah agreed, nice one!

@neerajdotname

This comment has been minimized.

Show comment Hide comment
@neerajdotname

neerajdotname Sep 27, 2010

Member

Although the underlying assumption here is that gusb! is faster than regex. Unless there is benchmarking data I don't really know. May be someone from ruby core ( Aaron Patterson) might be able to tell which one is faster.

If regex turns out to be faster than gsub! then we should stick with regex approach. Otherwise switch to gsub! .

Member

neerajdotname replied Sep 27, 2010

Although the underlying assumption here is that gusb! is faster than regex. Unless there is benchmarking data I don't really know. May be someone from ruby core ( Aaron Patterson) might be able to tell which one is faster.

If regex turns out to be faster than gsub! then we should stick with regex approach. Otherwise switch to gsub! .

@thedarkone

This comment has been minimized.

Show comment Hide comment
@thedarkone

thedarkone Sep 27, 2010

Contributor

I'd probably guess lazy gsub! to be slightly faster. I've also updated the gist (http://gist.github.com/599605) with a slightly better regexps, so somebody should run a bench and whip up a patch.

Contributor

thedarkone replied Sep 27, 2010

I'd probably guess lazy gsub! to be slightly faster. I've also updated the gist (http://gist.github.com/599605) with a slightly better regexps, so somebody should run a bench and whip up a patch.

@lsylvester

This comment has been minimized.

Show comment Hide comment
@lsylvester

lsylvester Sep 28, 2010

Contributor

I have run a benchmark at http://gist.github.com/600385

It looks like the lazy gsub! is faster.

          user     system      total        real
  orig:   1.660000   0.040000   1.700000 (  1.689658)
  mod1:   1.650000   0.030000   1.680000 (  1.693604)
  mod2:   1.370000   0.030000   1.400000 (  1.395524)
  mod3:   1.340000   0.020000   1.360000 (  1.358895)
  lazy:   0.930000   0.030000   0.960000 (  0.954206)
Contributor

lsylvester replied Sep 28, 2010

I have run a benchmark at http://gist.github.com/600385

It looks like the lazy gsub! is faster.

          user     system      total        real
  orig:   1.660000   0.040000   1.700000 (  1.689658)
  mod1:   1.650000   0.030000   1.680000 (  1.693604)
  mod2:   1.370000   0.030000   1.400000 (  1.395524)
  mod3:   1.340000   0.020000   1.360000 (  1.358895)
  lazy:   0.930000   0.030000   0.960000 (  0.954206)
@neerajdotname

This comment has been minimized.

Show comment Hide comment
@neerajdotname

neerajdotname Sep 28, 2010

Member

I'm blown away by the result. That's significant perf improvement.

Member

neerajdotname replied Sep 28, 2010

I'm blown away by the result. That's significant perf improvement.

Please sign in to comment.