Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Levels of Optimization Design Source Build Compile Runtime

Slide 6

Slide 6 text

Levels of Optimization Design Source Build Compile Runtime Architecture and algorithms (e.g. n + 1 queries) Writing fast Ruby Setting build flags (e.g. ./configure) mrbc, jrubyc, rbx compile Thanks Matz & Koichi (e.g. RUBY_GC_MALLOC_LIMIT)

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Benchmark require ‘benchmark' n = 50 Benchmark.bm do |x| x.report { n.times { fast } } x.report { n.times { slow } } end

Slide 9

Slide 9 text

Benchmark require ‘benchmark' n = 50_000 Benchmark.bm do |x| x.report { n.times { fast } } x.report { n.times { slow } } end

Slide 10

Slide 10 text

Benchmark IPS require 'benchmark/ips' Benchmark.ips do |x| x.report('fast') { fast } x.report('slow') { slow } end

Slide 11

Slide 11 text

Goals Source Significant Easy Happy Optimize at the code level At least 12% improvement Code should be easier to read High quality Ruby

Slide 12

Slide 12 text

Proc#call versus yield def slow(&block) block.call end def fast yield end

Slide 13

Slide 13 text

Results slow 950950.6 (±14.0%) i/s fast 5508226.3 (±15.5%) i/s Over 5X faster!

Slide 14

Slide 14 text

Proc#call versus yield def slow Proc.new.call end def fast yield end

Slide 15

Slide 15 text

Block versus Symbol#to_proc (1..100).map { |i| i.to_s } (1..100).map(&:to_s)

Slide 16

Slide 16 text

Results slow 47524.3 (±7.6%) i/s fast 56823.2 (±7.2%) i/s 20% faster!

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Enumerable#map and Array#flatten versus Enumerable#flat_map enum.map do # do something end.flatten(1) enum.flat_map do # do something end

Slide 20

Slide 20 text

Results slow 12348.2 (±9.0%) i/s fast 56647.8 (±7.2%) i/s Over 4.5X faster!

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Enumerable#reverse and Enumerable#each
 versus Enumerable#reverse_each enum.reverse.each do # do something end enum.reverse_each do # do something end

Slide 24

Slide 24 text

Results slow 156173.2 (±9.2%) i/s fast 182859.3 (±7.8%) i/s 17% faster!

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Hash#keys and Enumerable#each
 versus Hash#each_key hash.keys.each do |k| # do something end hash.each_key do |k| # do something end

Slide 27

Slide 27 text

Results slow 34702.1 (±9.8%) i/s fast 46103.3 (±8.1%) i/s Over 33% faster!

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Array#shuffle and Array#first
 versus Array#sample array.shuffle.first array.sample

Slide 31

Slide 31 text

Results slow 324806.7 (±8.1%) i/s fast 5069719.9 (±9.5%) i/s Over 15X faster!

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Hash#merge versus Hash#merge! enum.inject({}) do |h, e| h.merge(e => e) end enum.inject({}) do |h, e| h.merge!(e => e) end

Slide 35

Slide 35 text

Results slow 33572.0 (±3.3%) i/s fast 106473.0 (±3.4%) i/s Over 3X faster!

Slide 36

Slide 36 text

Hash#merge! versus Hash#[]= enum.each_with_object({}) do |e, h| h.merge!(e => e) end enum.each_with_object({}) do |e, h| h[e] = e end

Slide 37

Slide 37 text

Results slow 99331.3 (±2.2%) i/s fast 217944.4 (±5.2%) i/s Over 2X faster!

Slide 38

Slide 38 text

Hash#fetch versus Hash#fetch with block {:ruby => :conf}.fetch(:ruby, (0..9).to_a) {:ruby => :conf}.fetch(:ruby) { (0..9).to_a }

Slide 39

Slide 39 text

Results slow 712384.2 (±3.8%) i/s fast 1590417.4 (±4.1%) i/s Over 2X faster!

Slide 40

Slide 40 text

String#gsub versus String#sub ‘http://rubyconf.pt/'.gsub(‘http://', 'https://') 'http://rubyconf.pt/'.sub('http://', 'https://')

Slide 41

Slide 41 text

Results slow 404148.2 (±4.6%) i/s fast 602661.1 (±3.4%) i/s 50% faster!

Slide 42

Slide 42 text

String#gsub versus String#tr 'slug from title'.gsub(' ', '_') 'slug from title'.tr(' ', '_')

Slide 43

Slide 43 text

Results slow 311878.2 (±3.5%) i/s fast 1573891.1 (±4.6%) i/s Over 5X faster!

Slide 44

Slide 44 text

Parallel versus sequential assignment a, b = 1, 2 a = 1 b = 2

Slide 45

Slide 45 text

Results slow 5821588.3 (±6.0%) i/s fast 8010420.3 (±5.5%) i/s 40% faster!

Slide 46

Slide 46 text

Using exceptions for control flow begin ruby.conf rescue NoMethodError 'conf' end if ruby.respond_to?(:conf) ruby.conf else 'conf' end

Slide 47

Slide 47 text

Results slow 328886.4 (±5.0%) i/s fast 3348327.9 (±9.0%) i/s Over 10X faster!

Slide 48

Slide 48 text

Using throw/catch for control flow begin ruby.conf rescue NoMethodError 'conf' end catch(:ruby) do if ruby.respond_to?(:conf) ruby.conf else throw(:ruby, ‘conf’) end end

Slide 49

Slide 49 text

Results slow 252474.2 (±8.4%) i/s fast 1411916.6 (±7.2%) i/s Over 5X faster!

Slide 50

Slide 50 text

The Future

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

Special Thanks Aaron Patterson Ruby Rogues Parley Sam Saffron Aman Gupta Don Knuth Yukihiro Matsumoto Koichi Sasada RubyConf Portugal

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content