| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| |
| |
| | |
deivid-rodriguez/fix_undefined_method_error_on_exception
Fix undefined method error on exception
|
| |
| |
| |
| |
| |
| | |
The `error` method is not defined, in general, for exceptions. Instead,
print the exception message. This error was hiding actual meaningful DB
configuration errors. See http://stackoverflow.com/questions/18774463.
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Follow up #21591.
The document of limit option for a text column is incorrect.
MySQL: the limit is byte length, not character length
Pg, Sqlite3: variable unlimited length
|
|\ \
| | |
| | | |
TEXT and BLOB limit is byte length, not character length.
|
| | | |
|
|\ \ \
| |/ /
|/| | |
Updated MySQL documentation link to MySQL latest version 5.7 everywhe…
|
| | |
| | |
| | |
| | |
| | | |
skip]
Bumps from `5.6` to `5.7`
|
|/ /
| |
| |
| |
| | |
autoloading this could possibly cause some weird race condition
when calling an AR::Attribute's singleton method on a threaded server.
|
| |
| |
| |
| |
| |
| | |
The last call site of `last_version` was removed with:
838e18321118ee3ec6669217e5ea0216f79c969a
|
|\ \
| | |
| | | |
HasManyAssociation: moved half of counter cache code to reflection
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Current implementation has a lot of utility methods that accept
reflection call a lot of methods on it and exit.
E.g. has_counter_cache?(reflection)
It causes confusion and inability to cache result of the method even
through it always returns the same result for the same reflection
object.
It can be done easier without access to the association context
by moving code into reflection itself.
e.g. reflection.has_counter_cache?
Reflection is less complex object than association so moving code there
automatically makes it simplier to understand.
|
|\ \ \
| | | |
| | | |
| | | | |
Use `ActiveRecord::Tasks::DatabaseTasks.migrations_paths` explicit for db tasks
|
| | | |
| | | |
| | | |
| | | | |
`Migrator.migrations_paths`
|
| | | |
| | | |
| | | |
| | | | |
This method is private API and never used. Let's remove it.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
`Schema#migrations_paths` is not supposed to be public API. In fact
it's only used inside `Schema` itself, so let's make it private.
|
| | | |
| | | |
| | | |
| | | | |
It is always passed in
|
| | | | |
|
| | | |
| | | |
| | | |
| | | | |
Usage was removed in 5c4495538b
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
robertjlooby/fix_overwriting_by_dynamic_finders"
This reverts commit d5ba9a42a6e93b163a49f99d739aa56820e044d0, reversing
changes made to 30c503395bf6bf7db1ec0295bd661ce644628db5.
Reason: This generate the dynalic finders more than one time
|
|\ \ \ \
| | | | |
| | | | |
| | | | | |
put dynamic matchers on GeneratedAssociationMethods instead of model
|
| | | | | |
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Added nodoc tag for the methods which returns object of private apis
|
| | | | | | |
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | |
| | | | | | | |
Fix and Improve sql logging coloration in `ActiveRecord::LogSubscriber`.
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
- CR feedback from @egilburg
Additionally
- Move logic for colorizing the payload name into a separate method
- Make some `ActiveRecord::LogSubscriber` instance methods private for clarity:
- `colorize_payload_name`
- `sql_color`
- `logger`
- Improve Changelog Documentation
GH #20885
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
- Improves coloring for statements like:
# Become WHITE
SELECT * FROM (
SELECT * FROM mytable FOR UPDATE
) ss WHERE col1 = 5;
LOCK TABLE table_name IN ACCESS EXCLUSIVE MODE;
# Becomes RED
ROLLBACK
- Reinstates the coloration of the `payload[:name]`.
Instead of simple alternating colors, adds meaning:
- `MAGENTA` for `"SQL"` or `blank?` payload names
- `CYAN` for Model Load/Exists
- Introduces specs for sql coloration.
- Introduces specs for payload name coloration.
GH#20885
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
[ci skip]
@sgrif can you review when you have time? Thanks!
|
|\ \ \ \ \ \ \
| |_|/ / / / /
|/| | | | | | |
Validate multiple contexts on `valid?` and `invalid?` at once
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
Example:
```ruby
class Person
include ActiveModel::Validations
attr_reader :name, :title
validates_presence_of :name, on: :create
validates_presence_of :title, on: :update
end
person = Person.new
person.valid?([:create, :update]) # => true
person.errors.messages # => {:name=>["can't be blank"], :title=>["can't be blank"]}
```
|
|\ \ \ \ \ \ \
| | | | | | | |
| | | | | | | | |
Removes mandatory arguments from AR exceptions
|
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
This change allows to instantiate all ActiveRecordError descendant
execption classes without arguments, which might be useful in testing
and is far less surprising than mandatory arguments.
|
|\ \ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Define `SchemaStatements#tables` as interface
|
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
These 3 methods expect `ConnectionAdapters` to have `tables` method,
so make it clear that `tables` method is interface.
* `ConnectionAdapters::SchemaCache#prepare_tables`
* `db:schema:cache:dump` task
* `SchemaDumper#tables`
|
|\ \ \ \ \ \ \ \ \
| | | | | | | | | |
| | | | | | | | | | |
Replace AR with ActiveRecord to make it more readable [ci skip]
|
| |/ / / / / / / / |
|
|\ \ \ \ \ \ \ \ \
| |/ / / / / / / /
|/| | | | | | | | |
Add tests for test/cases/adapters/mysql2/view_test.rb
|
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Basically view tests for MySQL are same with
`test/cases/adapters/postgresql/view_test.rb`.
So move `test/cases/adapters/postgresql/view_test.rb` to
`test/cases/view_test.rb` and make them only run if
`current_adapter` supports writable view.
|
| | | | | | | | | |
|
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Its value never change since associations are defined at class load time
so there is no need to build the hash everytime the method is called.
Before this change:
Calculating -------------------------------------
reflections 804.000 i/100ms
-------------------------------------------------
reflections 8.213k (±26.2%) i/s - 36.180k
After this change:
Calculating -------------------------------------
reflections 24.548k i/100ms
-------------------------------------------------
reflections 1.591M (±25.7%) i/s - 7.364M
Benchmark script:
require 'bundler/setup'
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
100.times do |i|
create_table "users#{i}", force: true
end
create_table :cars, force: true do |t|
100.times do |i|
t.references "users#{i}"
end
end
end
class Car < ActiveRecord::Base
100.times do |i|
belongs_to "users#{i}".to_sym
end
end
Benchmark.ips do |x|
x.report('reflections') { Car.reflections }
end
|
|\ \ \ \ \ \ \ \ \
| | | | | | | | | |
| | | | | | | | | | |
PERF: Reduce allocation in `resolve_column_aliases`.
|
| | |_|/ / / / / /
| |/| | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Benchmark Script Used:
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', path: '~/rails' # master against ref "f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06"
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
gem 'sass'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'pg'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.timestamps null: false
end
end
class User < ActiveRecord::Base; end
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
}
1000.times { User.create!(attributes) }
Benchmark.ips(5, 3) do |x|
x.report('where with hash single') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.report('where with string single') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.report('where with hash double') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", email: "foobar@email.com") }
x.report('where with string double') { User.where("users.name = ? AND users.email = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "foobar@email.com") }
x.compare!
end
```
Before:
```
Calculating -------------------------------------
where with hash single
3.300k i/100ms
where with string single
4.965k i/100ms
where with hash double
2.594k i/100ms
where with string double
4.400k i/100ms
-------------------------------------------------
where with hash single
35.161k (± 1.2%) i/s - 178.200k
where with string single
53.368k (± 2.9%) i/s - 268.110k
where with hash double
27.364k (± 1.1%) i/s - 137.482k
where with string double
46.876k (± 2.1%) i/s - 237.600k
Comparison:
where with string single: 53368.1 i/s
where with string double: 46875.5 i/s - 1.14x slower
where with hash single: 35160.8 i/s - 1.52x slower
where with hash double: 27364.0 i/s - 1.95x slower
```
After:
```
Calculating -------------------------------------
where with hash single
3.403k i/100ms
where with string single
5.167k i/100ms
where with hash double
2.659k i/100ms
where with string double
4.597k i/100ms
-------------------------------------------------
where with hash single
36.410k (± 1.3%) i/s - 183.762k
where with string single
55.009k (± 2.6%) i/s - 279.018k
where with hash double
27.951k (± 1.4%) i/s - 140.927k
where with string double
48.362k (± 2.6%) i/s - 243.641k
Comparison:
where with string single: 55008.6 i/s
where with string double: 48361.5 i/s - 1.14x slower
where with hash single: 36410.1 i/s - 1.51x slower
where with hash double: 27950.9 i/s - 1.97x slower
```
|
|/ / / / / / / /
| | | | | | | |
| | | | | | | |
| | | | | | | | |
Known failure on Ruby 2.3/trunk: brianmario/mysql2#671
|
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
Related with #20418
|
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
dmitry/feature/validate-multiple-contexts-at-once"
This reverts commit 51dd2588433457960cca592d5b5dac6e0537feac, reversing
changes made to ecb4e4b21b3222b823fa24d4a0598b1f2f63ecfb.
This broke Active Record tests
|
|\ \ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Validate multiple contexts on `valid?` and `invalid?` at once
|
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Example:
```ruby
class Person
include ActiveModel::Validations
attr_reader :name, :title
validates_presence_of :name, on: :create
validates_presence_of :title, on: :update
end
person = Person.new
person.valid?([:create, :update]) # => true
person.errors.messages # => {:name=>["can't be blank"], :title=>["can't be blank"]}
```
|
|\ \ \ \ \ \ \ \ \
| | | | | | | | | |
| | | | | | | | | | |
PERF: Scope performance.
|
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | | |
Benchmark Script:
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
# gem 'rails', github: 'rails/rails', ref: 'f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06'
gem 'rails', path: '~/rails'
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
gem 'sass'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'pg'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.timestamps null: false
end
end
class User < ActiveRecord::Base; end
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
}
1000.times { User.create!(attributes) }
Benchmark.ips(5, 3) do |x|
x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.compare!
end
key =
if RUBY_VERSION < '2.2'
:total_allocated_object
else
:total_allocated_objects
end
before = GC.stat[key]
User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
after = GC.stat[key]
puts "Total Allocated Object: #{after - before}"
```
Stackprof output truncated.
```
TOTAL (pct) SAMPLES (pct) FRAME
52 (10.6%) 10 (2.0%) ActiveRecord::Scoping::Default::ClassMethods#build_default_scope
```
Before:
```
Calculating -------------------------------------
where with hash 2.789k i/100ms
where with string 4.407k i/100ms
-------------------------------------------------
where with hash 29.170k (± 1.9%) i/s - 147.817k
where with string 46.954k (± 2.7%) i/s - 237.978k
Comparison:
where with string: 46954.3 i/s
where with hash: 29169.9 i/s - 1.61x slower
Total Allocated Object: 85
Calculating -------------------------------------
all 16.773k i/100ms
-------------------------------------------------
all 186.102k (± 3.6%) i/s - 939.288k
```
After:
```
Calculating -------------------------------------
where with hash 3.014k i/100ms
where with string 4.623k i/100ms
-------------------------------------------------
where with hash 31.524k (± 1.3%) i/s - 159.742k
where with string 49.948k (± 2.3%) i/s - 249.642k
Comparison:
where with string: 49948.3 i/s
where with hash: 31524.3 i/s - 1.58x slower
Total Allocated Object: 84
Calculating -------------------------------------
all 20.139k i/100ms
-------------------------------------------------
all 227.860k (± 2.5%) i/s - 1.148M
```
|
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | | |
Stackprof output truncated.
```
TOTAL (pct) SAMPLES (pct) FRAME
23 (4.7%) 12 (2.4%) Hash#transform_keys
11 (2.2%) 11 (2.2%) block in Hash#transform_keys
30 (6.1%) 7 (1.4%) Hash#stringify_keys
```
Benchmark Script:
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', path: '~/rails' # master against ref "f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06"
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
gem 'sass'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'pg'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.timestamps null: false
end
end
class User < ActiveRecord::Base; end
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
}
1000.times { User.create!(attributes) }
Benchmark.ips(5, 3) do |x|
x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.compare!
end
key =
if RUBY_VERSION < '2.2'
:total_allocated_object
else
:total_allocated_objects
end
before = GC.stat[key]
User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
after = GC.stat[key]
puts "Total Allocated Object: #{after - before}"
```
Before:
```
Calculating -------------------------------------
where with hash 2.796k i/100ms
where with string 4.338k i/100ms
-------------------------------------------------
where with hash 29.177k (± 1.5%) i/s - 148.188k
where with string 47.419k (± 2.8%) i/s - 238.590k
Comparison:
where with string: 47419.0 i/s
where with hash: 29176.6 i/s - 1.63x slower
Total Allocated Object: 85
```
After:
```
Calculating -------------------------------------
where with hash 2.895k i/100ms
where with string 4.416k i/100ms
-------------------------------------------------
where with hash 30.758k (± 2.0%) i/s - 156.330k
where with string 47.708k (± 2.6%) i/s - 238.464k
Comparison:
where with string: 47707.9 i/s
where with hash: 30757.7 i/s - 1.55x slower
Total Allocated Object: 84
```
|
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | | |
Generic cast-to-text was only added in 8.3.
|