Slide 1

Slide 1 text

M icro-optim izing Ruby For big wins!

Slide 2

Slide 2 text

You shouldn’t do it. Um, what? I guess we’re done.

Slide 3

Slide 3 text

Bigger Optimizations • SQL queries • n + 1 queries • Ruby version • server software • server configuration • caching • sharding Smarter Co-workers

Slide 4

Slide 4 text

You should do it.

Slide 5

Slide 5 text

You’ll learn more about Ruby. 1

Slide 6

Slide 6 text

Technically Faster The best kind of faster. 2

Slide 7

Slide 7 text

Small changes can add up. 3

Slide 8

Slide 8 text

Richard Schneems

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

-37,452

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

.freeze

Slide 13

Slide 13 text

5.times do 'hell' end

Slide 14

Slide 14 text

5.times do 'hell'.freeze end

Slide 15

Slide 15 text

a few caveats

Slide 16

Slide 16 text

pry> 2.frozen? => true pry> :hi.frozen? => true

Slide 17

Slide 17 text

pry> 10.times { 'hello' } Total allocated: 400 bytes (10 objects) pry> h = {} pry> 10.times { h['hello'] } Total allocated: 40 bytes (1 objects)

Slide 18

Slide 18 text

pry> ['hello', 'world'].freeze => ["hello", "world"] pry> _.first.frozen? => false

Slide 19

Slide 19 text

name = 'world'.freeze "hello #{name}".freeze

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

pry> word = 'hello' => "hello" pry> word.gsub('h', 'c') => "cello" pry> word => "hello"

Slide 22

Slide 22 text

pry> word = 'hello' => "hello" pry> word.gsub!('h', 'c') => "cello" pry> word => "cello"

Slide 23

Slide 23 text

a caveat

Slide 24

Slide 24 text

pry> word.gsub('a', 'b') => "hello" pry> word.gsub!('a', 'b') => nil

Slide 25

Slide 25 text

pry> [2, 4, 6].select!(&:even?) => nil pry> [2, 4, 6].keep_if(&:even?) => [2, 4, 6] pry> [2, 4, 6].reject!(&:odd?) => nil pry> [2, 4, 6].delete_if(&:odd?) => [2, 4, 6]

Slide 26

Slide 26 text

optim ized m ethods

Slide 27

Slide 27 text

We can make it better! keys.each map {}.flatten reverse.each each.with_index each.with_object

Slide 28

Slide 28 text

We can make it better! keys.each map {}.flatten reverse.each each.with_index each.with_object each_key reverse_each each_with_object each_with_index flat_map {}

Slide 29

Slide 29 text

If you see two existing methods joined with an underscore. It’s probably an optimization.

Slide 30

Slide 30 text

colors .reverse .each do |color| puts color end

Slide 31

Slide 31 text

colors .reverse .each do |color| puts color end

Slide 32

Slide 32 text

colors .reverse_each do |c| puts c end

Slide 33

Slide 33 text

colors .reverse .each colors .reverse_each

Slide 34

Slide 34 text

a caveat

Slide 35

Slide 35 text

colors .reverse .each colors .reverse_each

Slide 36

Slide 36 text

som e things you just have to know

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Calculating ------------------------------------- String#=~ 56.672k i/100ms String#start_with? 118.308k i/100ms ------------------------------------------------- String#=~ 919.574k (± 6.4%) i/s - 4.590M String#start_with? 4.177M (± 6.4%) i/s - 20.822M Comparison: String#start_with?: 4177162.6 i/s String#=~: 919574.2 i/s - 4.54x slower

Slide 40

Slide 40 text

benchmark-ips

Slide 41

Slide 41 text

require 'benchmark/ips' Benchmark.ips do |x| x.report('fast code') do fast end x.report('slow code') do slow end x.compare! end

Slide 42

Slide 42 text

Calculating ------------------------------------- fast 85.749k i/100ms slow 35.529k i/100ms ------------------------------------------------- fast 1.867M (± 7.6%) i/s - 9.347M slow 467.095k (± 6.4%) i/s - 2.345M Comparison: fast: 1866669.5 i/s slow: 467095.4 i/s - 4.00x slower

Slide 43

Slide 43 text

memory_profiler

Slide 44

Slide 44 text

require 'memory_profiler' MemoryProfiler.report do code.to.run end.pretty_print

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

questions?