Last active
August 29, 2015 14:16
-
-
Save NikitaAvvakumov/7d1e9efe300aef7f8b8f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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