1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

call sync_with_transaction_state inside persisted? then check ivars

directly

calling `sync_with_transaction_state` is not fast, so if we call it
once, we can improve the performance of the `persisted?` method.  This
is important because every call to `url_for(model)` will call
`persisted?`, so we want that to be fast.

Here is the benchmark:

```ruby
require 'active_record'

ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"

ActiveRecord::Base.connection.instance_eval do
  create_table(:articles)
end

class Article < ActiveRecord::Base; end
article = Article.new.tap(&:save!)

Benchmark.ips do |x|
  x.report("persisted?") do
    article.persisted?
  end
end
```

Before this patch:

```
$ bundle exec ruby -rbenchmark/ips persisted.rb
Calculating -------------------------------------
          persisted?     3.333k i/100ms
-------------------------------------------------
          persisted?     51.037k (± 8.2%) i/s -    253.308k
```

After:

```
$ bundle exec ruby -rbenchmark/ips persisted.rb
Calculating -------------------------------------
          persisted?     7.172k i/100ms
-------------------------------------------------
          persisted?    120.730k (± 5.1%) i/s -    602.448k
```
This commit is contained in:
Aaron Patterson 2015-03-02 07:51:29 -08:00
parent 10058ea280
commit 57d35b2bf9

View file

@ -96,7 +96,8 @@ module ActiveRecord
# Returns true if the record is persisted, i.e. it's not a new record and it was
# not destroyed, otherwise returns false.
def persisted?
!(new_record? || destroyed?)
sync_with_transaction_state
!(@new_record || @destroyed)
end
# Saves the model.