for writing efficient code
str = s1.to_s + " " + s2.to_s + " " + s3.to_s
fast
str = "#{s1} #{s2} #{s3}"
#String
+ << "#{}"
sub sub!
gsub gsub!
#Hash
merge merge!
#Array
+ concat
map map!
compact compact!
uniq uniq!
flatten flatten!
self.var = "requires walking the AST, and results in multiple lookups"
fast
@var = "local variable, cached by Ruby, and requires a single lookup"
# Symbol.to_proc method, order of magniture slower...
@widget_ids = @widgets.map(&:id)
# same effect, not as pretty, but much faster
@widget_ids = @widgets.inject([]) {|w, a| w.push(a.id)}
# faster, and simpler than inject
@widget_ids = @widgets.collect {|w| w.id }
# yet another (faster) way to tackle the problem
@widget_ids = @widgets.map {|w| w.id }
User.all.each do |user|
user_hash[user.id] = user.name
end
do
User.select([:id, :name]).each do |user|
user_hash[user.id] = user.name
end
User.all.collect(:id)
User.select(:id).collect(&:id)
do
User.pluck(:id)
program.groups.each do |group|
group.connection_memberships.each do |membership|
membership.send_email
end
end
do
Connection::Membership.joins(:group).where('groups.program_id = ?', program.id).each do |membership|
membership.send_email
end
groups.includes(:connection_memberships).each do |group|
group.memberships.find_by_id(membership.id)
end
do
groups.includes(:connection_memberships).each do |group|
group.memberships.find{|mem| mem.id == membership.id}
end
SELECT id
FROM users
WHERE member_id IN (SELECT id from members where admin = true)
do
SELECT id
FROM users LEFT JOIN members ON users.member_id = members.id
WHERE members.admin = true
User.all.each do |user|
if user.pending_notifications.size > 0
user.send_email
end
end
do
pending_notifications = PendingNotification.group_by(&:user_id)
User.each do |user|
if pending_notifications[user.id].present?
user.send_email
end
end
data = []
elements.each do |element|
data << element.id unless data.include?(element.id)
end
do
data = {}
elements.each do |element|
data[element.id] = element.id
end
data = data.keys # if needed
calendar_meetings = {}
User.each do |user|
calendar_meetings[user.id] = user.meetings.with_calendar_time_available.size
end
do
calendar_meetings = {}
User.where(meetings: {calendar_time_available: true}).each do |user|
calendar_meetings[user.id] = user.meetings.with_calendar_time_available.size
end
SELECT id from users WHERE member_id IN (1, 2, 3, ........100000)
do
SELECT id from users LEFT JOIN members ON users.member_id = members.id WHERE members.admin = true
User.each do |user|
user.send_email
end
do
User.find_each do |user|
user.send_email
end
find_in_batches
batch_size
(0.3ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 1
(0.3ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 2
(0.2ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 3
(1.1ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 4
(1.0ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 5
(1.1ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 6
(0.5ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 7
(0.3ms) SELECT COUNT(*) FROM "wheels" WHERE "wheels"."vehicle_id" = 8
class Wheel < ActiveRecord::Base
belongs_to :vehicle, counter_cache: true
end
class Vehicle < ActiveRecord::Base
has_many :wheels
end
# config/environments/development.rb
config.after_initialize do
Bullet.enable = false
Bullet.alert = true
Bullet.bullet_logger = true
Bullet.console = true
Bullet.rails_logger = true
Bullet.disable_browser_cache = true
end
require 'benchmark'
LOOP_COUNT = 1_000_000
x = ["1","2","3"]
Benchmark.bmbm do |test|
test.report("Method invoke") do
LOOP_COUNT.times {x.map {|elem| elem.to_i}}
end
test.report("Symbol.to_proc") do
LOOP_COUNT.times {x.map(&:to_i)}
end
end
--------------------------------------------------
Method invoke 1.600000 0.000000 1.600000 ( 1.783758)
Symbol.to_proc 13.240000 0.070000 13.310000 ( 13.770514)
---------------------------------------- total: 14.910000sec
user system total real
Method invoke 1.590000 0.010000 1.600000 ( 1.628473)
Symbol.to_proc 13.210000 0.060000 13.270000 ( 13.678768)
Firefox
delayed_job, resque, sidekiq etc.