Skip to content

Instantly share code, notes, and snippets.

@NikitaAvvakumov
Last active August 29, 2015 14:16
Show Gist options
  • Save NikitaAvvakumov/7d1e9efe300aef7f8b8f to your computer and use it in GitHub Desktop.
Save NikitaAvvakumov/7d1e9efe300aef7f8b8f to your computer and use it in GitHub Desktop.
# from http://youtu.be/fGFM_UrSp70
def slow(&block)
block.call
end
def fast
yield # 5x faster than passing a block as an argument
end
#####################
(1..100).map { |i| i.to_s } # slow
(1..100).map(&:to_s) # faster by 20%
#####################
enum.map do
# code
end.flatten(1) # 2 passes through the enum - slow
enum.flat_map do
# code
end # single pass through the enum - 4.5x faster
#####################
enum.inject({}) do |h, e|
h.merge(e => e) # hash is duplicated and modified, new (increasingly larger) object allocated each time
end
enum.inject({}) do |h, e|
h.merge!(e => e) # merge! modifies the hash in place, no new object allocation - 3x faster
end
enum.inject({}) do |h, e|
h[e] = e # new { e => e } hash is not allocated each time for merging - 2x faster still
end
#####################
# Hash#fetch retrieves a value from a hash. If the key is not found in the hash,
# it can return a default value, which can be provided as a second argument or
# as a block
{ :foo => 'bar' }.fetch(:bar, (0..9).to_a) # slow - the array of 10 Fixnums is allocated on every call
{ :foo => 'bar' }.fetch(:bar) { (0..9).to_a } # the block is not evaluated unless the key is not found
# - 2x faster when the key is present in the hash
{ :foo => 'bar' }[:foo] || (0..9).to_a # may be faster still; benchmark
# Update: in my hands, method #3 is 2x faster than method #2, which is 6x faster than method #1
# When the hash key is missing, #1 runs as before, #3 runs as #1, and #2 runs ~10% slower
#####################
'http://example.com'.gsub('http://', 'https://') # even if a single substitution is desired, scans the entire string
'http://example.com'.sub('http://', 'https://') # replaces and stops; more intention-revealing if a single substitution is needed
# - 50% faster even on short target string
'slug from name'.tr(' ', '_') # 5x faster than same with `gsub`
#####################
a, b = 1, 2
a = 1
b = 2 # 40% faster and far more readable
#####################
begin
foo
rescue NoMethodError
bar
end
if respond_to?(:foo)
foo
else
bar
end # 10x faster
#####################
array.each_with_index do |element, index|
# do something with element & index
end
index = 0
while index < array.size do
# do something with array[index] & index
index += 1
end # 80% faster, at the cost of readability & Ruby-ness
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment