Skip to content

Commit

Permalink
Improve performance in sql.activerecord subscription callback
Browse files Browse the repository at this point in the history
I was memory profiling a particularly slow system spec, and these two
lines popped up on my radar. It's calling `caller` twice, and then
duplicating one of them.

`caller` is pretty well understood as being pretty slow, so calling it
only once is an Improve.

The second call was using `dup`. This should not be necessary, as
`caller` returns a new object anyways. Even when calling `caller` once,
we don't do any manipulation of it, so it's safe to remove the `dup`

In my specific spec, I saw an improvement from 2m18s to 1m58s. I also
did a micro benchmark showing the difference:

```ruby
require 'benchmark/ips'
require 'digest'

def original
  location_key = Digest::SHA1.hexdigest(caller.join)
  caller.dup
end

def refactored
  query_caller = caller
  location_key = Digest::SHA1.hexdigest(query_caller.join)
  query_caller
end

Benchmark.ips do |x|
  x.report("original") { original }
  x.report("refactored") { refactored }
  x.compare!
end
```

Which gives us:

```
Warming up --------------------------------------
            original    15.465k i/100ms
          refactored    25.355k i/100ms
Calculating -------------------------------------
            original    150.987k (± 1.3%) i/s -    757.785k in   5.019798s
          refactored    253.851k (± 1.3%) i/s -      1.293M in   5.094844s

Comparison:
          refactored:   253850.9 i/s
            original:   150987.3 i/s - 1.68x  slower
```
  • Loading branch information
technicalpickles committed Aug 7, 2023
1 parent 94f2320 commit b7a9f1f
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions lib/prosopite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,14 @@ def subscribe
sql, name = data[:sql], data[:name]

if scan? && name != "SCHEMA" && sql.include?('SELECT') && data[:cached].nil? && !ignore_query?(sql)
location_key = Digest::SHA1.hexdigest(caller.join)
query_caller = caller
location_key = Digest::SHA1.hexdigest(query_caller.join)

tc[:prosopite_query_counter][location_key] += 1
tc[:prosopite_query_holder][location_key] << sql

if tc[:prosopite_query_counter][location_key] > 1
tc[:prosopite_query_caller][location_key] = caller.dup
tc[:prosopite_query_caller][location_key] = query_caller.dup
end
end
end
Expand Down

0 comments on commit b7a9f1f

Please sign in to comment.