なるようになるブログ

読書感想文かrailsについてかrubyについてか

rails commit log流し読み(2015/09/07)

2015/09/07分のコミットです。

CHANGELOGにのったコミットは以下の通りです。

activerecord/CHANGELOG.md


Fix test failures from premature merge of #21317

activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rbactiverecord/test/cases/adapters/postgresql/active_schema_test.rbのの修正です。

Support dropping indexes concurrently in Postgresの対応により、既存のindexの追加/削除のテストがエラーになってしまった為、修正しています。


[ci skip] Replace AR with Active Record in task desc

activerecord/lib/active_record/railties/databases.rakeの修正です。

db:schema:dumptaskのdescに、Active Recordを省略形(AR)で記載していたのを、正式名称(Active Record)で記載するよう修正しています。


Reduce calls to stringify_keys.

Active Recordの修正です。

scopeメソッドの性能改善として、stringify_keysメソッドの呼び出し回数を減らすようリファクタリングを行っています。


Cache check if default_scope has been overridden.

Active Recordの修正です。

こちらも先ほどのコミット同様scopeメソッドの性能改善対応です。こちらでは、default_scopeの生成処理で、default_scopeが上書き済みかどうかチェックし、上書き済みの場合はdefault_scopeの生成処理を行わないよう修正しています。

先のコミットと合わせての、性能改善結果は下記のとおりです。

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}"

Benchmark.ips(5, 3) do |x|
  x.report('all') { User.all }
end

Before:

Calculating -------------------------------------
     where with hash     2.727k i/100ms
   where with string     4.202k i/100ms
-------------------------------------------------
     where with hash     28.893k (± 1.8%) i/s -    144.531k
   where with string     44.463k (± 3.0%) i/s -    222.706k

Comparison:
   where with string:    44463.1 i/s
     where with hash:    28893.2 i/s - 1.54x slower

Total Allocated Object: 85
Calculating -------------------------------------
                 all    16.155k i/100ms
-------------------------------------------------
                 all    177.896k (± 3.7%) i/s -    904.680k

After:

Calculating -------------------------------------
     where with hash     3.207k i/100ms
   where with string     4.732k i/100ms
-------------------------------------------------
     where with hash     33.849k (± 1.1%) i/s -    169.971k
   where with string     49.735k (± 2.3%) i/s -    250.796k

Comparison:
   where with string:    49734.8 i/s
     where with hash:    33848.8 i/s - 1.47x slower

Total Allocated Object: 83
Calculating -------------------------------------
                 all    19.699k i/100ms
-------------------------------------------------
                 all    222.530k (± 2.6%) i/s -      1.123M

Merge pull request #21480 from amitsuroliya/add_return_value_description

actionview/lib/action_view/template.rbのdocの修正です。

Template#supports_streaming?メソッドのdocの修正です。

戻り値について説明している箇所の、グラマーの修正を行っています。


Merge pull request #21250 from ronakjangir47/safe_const

activesupport/test/constantize_test_cases.rbの修正です。

safe_constantizeメソッドに、存在しないObjectクラスのクラス名を指定した場合のテストを追加しています。


PERF: Don't create a Relation when it is not needed.

activerecord/lib/active_record/scoping/default.rbの修正です。

Active Recordの修正です。

default_scopeを生成する際、既に生成済みであれば、不要なRelationオブジェクトを生成しないようリファクタリングしています。こちらも性能改善対応の一環のようです。


Fix strange messages for rails g foo

railties/lib/rails/generators.rbの修正です。

generatorで、コマンド名をタイポした時に表示するサジェスチョンメッセージで、メッセージのつなぎの部分だけ中途半端にi18n対応されてしまっていたのを、全て英語のメッセージが表示されるよう対応しています。

例。(localeがjaの場合)

# before

Could not find generator 'foo'. Maybe you meant 'job'と'task' or 'cell'
Run rails generate --help for more options.

# after

Could not find generator 'foo'. Maybe you meant 'job', 'task' or 'cell'
Run rails generate --help for more options.

to_sentenceメソッドを使用してメッセージを組み立てているのですが、localeを明示的に指定していなかった為に発生してしまっていたようです。


changelog, minor formatting changes.

activerecord/CHANGELOG.mdの終了です。

CHANGELOGのグラマー、タイポの修正を行っています。


Allow global migrations_path configuration with using value from database_tasks instead of Migrator

activerecord/lib/active_record/tasks/database_tasks.rbの修正です。

bin/rake db:migrateが、処理実行時に、Migrator.migrations_pathsの代わりにActiveRecord::Tasks::DatabaseTasks.migrations_pathsに設定された値を使用するよう修正しています。

本来configで指定したmigrations_pathsを使用するのが正しい挙動なので、一応バグ修正ですかねえ。