Skip to content

Instantly share code, notes, and snippets.

@sonalkr132
Created February 20, 2019 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sonalkr132/3498b7d49bc021f84ed1ed7b8e3c8a4e to your computer and use it in GitHub Desktop.
Save sonalkr132/3498b7d49bc021f84ed1ed7b8e3c8a4e to your computer and use it in GitHub Desktop.
Warming up --------------------------------------
reorder_versions 1.000 i/100ms
reorder_versions_bulk
1.000 i/100ms
reorder_versions_prep
1.000 i/100ms
Calculating -------------------------------------
reorder_versions 0.277 (_ 0.0%) i/s - 2.000 in 7.230304s
reorder_versions_bulk
3.749 (_ 0.0%) i/s - 19.000 in 5.078283s
reorder_versions_prep
3.481 (_ 0.0%) i/s - 18.000 in 5.198946s
Comparison:
reorder_versions_bulk: 3.7 i/s
reorder_versions_prep: 3.5 i/s - 1.08x slower
reorder_versions: 0.3 i/s - 13.55x slower
def reorder_versions
numbers = reload.versions.sort.reverse.map(&:number).uniq
versions.each do |version|
Version.find(version.id).update_column(:position, numbers.index(version.number))
end
versions.update_all(latest: false)
versions_of_platforms = versions
.release
.indexed
.group_by(&:platform)
versions_of_platforms.each_value do |platforms|
Version.find(platforms.max.id).update_column(:latest, true)
end
end
def reorder_versions_bulk
numbers = reload.versions.sort.reverse.map(&:number).uniq
ids, positions = Array.new, Array.new
versions.each do |version|
ids << version.id
positions << numbers.index(version.number)
end
bulk_sql = <<-SQL
update versions set position = data_table.position, latest = false
from
(select unnest(array#{ids}) as id,
unnest(array#{positions}) as position) as data_table
where versions.id = data_table.id;
SQL
ActiveRecord::Base.connection.execute(bulk_sql)
versions_of_platforms = versions
.release
.indexed
.group_by(&:platform)
versions_of_platforms.each_value do |platforms|
Version.find(platforms.max.id).update_column(:latest, true)
end
end
def reorder_versions_prep
numbers = reload.versions.sort.reverse.map(&:number).uniq
sql = %q{
PREPARE fooplan (int, int) AS
UPDATE versions
SET position=$2,
latest=false
WHERE id=$1;
BEGIN;}
versions.each do |v|
sql << "EXECUTE fooplan(#{v.id}, '#{numbers.index(v.number)}');"
end
sql << 'COMMIT;DEALLOCATE fooplan;'
ActiveRecord::Base.connection.execute(sql)
versions_of_platforms = versions
.release
.indexed
.group_by(&:platform)
versions_of_platforms.each_value do |platforms|
Version.find(platforms.max.id).update_column(:latest, true)
end
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("reorder_versions") do
gems = ["nokogiri", "mocha", "activerecord"]
gems.each do |name|
Rubygem.find_by(name: name).reorder_versions
end
end
x.report("reorder_versions_bulk") do
gems = ["nokogiri", "mocha", "activerecord"]
gems.each do |name|
Rubygem.find_by(name: name).reorder_versions_bulk
end
end
x.report("reorder_versions_prep") do
gems = ["nokogiri", "mocha", "activerecord"]
gems.each do |name|
Rubygem.find_by(name: name).reorder_versions_prep
end
end
x.compare!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment