SlideShare a Scribd company logo
1 of 62
Download to read offline
Ruby Performance Secrets and 
How to Uncover Them 
http://www.slideshare.net/adymo/adymo-rubyconf-performance
Who am I? 
Alexander Dymo 
C/C++ since 2000 
Ruby/Rails since 2006 
Started to optimize back in 2007 
Never stopped since then
Rails Performance: What You Need to Know 
https://www.airpair.com/ruby-on-rails/performance 
Make Your Ruby/Rails App Fast: Performance And Memory 
Profiling Using ruby-prof and Kcachegrind 
http://www.acunote.com/blog/2008/02/make-your-ruby-rails-applications-fast-performance-and-memory-profiling.html 
Ruby Performance Tuning 
http://theprosegarden.com/contents-of-recent-issues/#10-14
Ruby 
Performance 
The first comprehensive book 
on Ruby Performance 
I'm 50% done. Beta soon. 
ruby-performance-book.com
Big thanks to:
What do we talk about today? 
Performance tips 
Performance best practices
What do we talk about today? 
Performance tips 
Performance best practices 
How to understand what's wrong 
How to find your own performance tips/best practices
In examples
Example 1
What can go wrong with this code?
What can go wrong with this code?
This was faster
100-200ms faster 
Sometimes 
…
Smells like...
https:// www.flickr.com/photos/timquijano/5720765523/
Let's check what happens:
Let's profile memory allocations 
Need patched ruby 
rvm reinstall 1.9.3 --patch railsexpress 
rvm reinstall 2.0.0 --patch railsexpress 
rvm reinstall 2.1.4 --patch railsexpress
Let's profile memory allocations 
Need profiler 
gem install ruby-prof
Let's profile memory allocations 
Need visualization tool 
Mac: 
brew install qcachegrind 
Linux: 
<your package manager> install kcachegrind 
Windows: 
http://sourceforge.net/projects/qcachegrindwin/
Let's profile memory allocations 
ruby-prof -p call_tree –mode=allocations before.rb > 
callgrind.out.before 
ruby-prof -p call_tree –mode=allocations after.rb > 
callgrind.out.after 
kcachegrind callgrind.out.before 
kcachegrind callgrind.out.after
static VALUE enum_inject(int argc, VALUE *argv, VALUE obj) 
{ 
NODE *memo; 
VALUE init, op; 
rb_block_call_func *iter = inject_i; 
… 
memo = NEW_MEMO(init, argc, op); 
rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); 
return memo->u1.value; 
}
> gdb `rbenv which ruby` 
GNU gdb (GDB) SUSE (7.5.1-2.5.1) 
Reading symbols from 
/home/gremlin/.rbenv/versions/2.1.4/bin/ruby...done. 
(gdb)
(gdb) l enum_inject 
632 * longest 
#=> "sheep" 
633 * 
634 */ 
635 static VALUE 
636 enum_inject(int argc, VALUE *argv, VALUE obj) 
637 { 
638 NODE *memo; 
639 VALUE init, op; 
640 rb_block_call_func *iter = inject_i; 
641 ID id; 
(gdb)
636 enum_inject(int argc, VALUE *argv, VALUE obj) 
637 { 
638 NODE *memo; 
639 VALUE init, op; 
640 rb_block_call_func *iter = inject_i; 
641 ID id; 
(gdb) b 638 
Breakpoint 1 at 0x1cbc0a: file enum.c, line 638. 
(gdb)
(gdb) r -e '[1,2,3].inject {}' 
Starting program: 
/home/gremlin/.rbenv/versions/2.1.4/bin/ruby -e 
'[1,2,3].inject {}' 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib64/libthread_db.so.1". 
[New Thread 0x7ffff7ff2700 (LWP 3893)] 
Breakpoint 1, enum_inject (argc=0, argv=<optimized out>, 
obj=93825001586240) at enum.c:640 
640 rb_block_call_func *iter = inject_i; 
(gdb)
640 rb_block_call_func *iter = inject_i; 
(gdb) n 
665 memo = NEW_MEMO(init, argc, op); 
(gdb)
640 rb_block_call_func *iter = inject_i; 
(gdb) n 
665 memo = NEW_MEMO(init, argc, op); 
(gdb) n 
666 rb_block_call(obj, id_each, 0, 0, iter, 
(VALUE)memo); 
(gdb)
640 rb_block_call_func *iter = inject_i; 
(gdb) n 
665 memo = NEW_MEMO(init, argc, op); 
(gdb) n 
666 rb_block_call(obj, id_each, 0, 0, iter, 
(VALUE)memo); 
(gdb) s 
rb_block_call (obj=93825001586240, mid=1456, argc=0, 
argv=0x0, bl_proc=0x555555722460 <inject_i>, 
data2=93825001586200) at vm_eval.c:1142 
1142 { 
(gdb)
640 rb_block_call_func *iter = inject_i; 
(gdb) n 
665 memo = NEW_MEMO(init, argc, op); 
(gdb) n 
666 rb_block_call(obj, id_each, 0, 0, iter, 
(VALUE)memo); 
(gdb) s 
rb_block_call (obj=93825001586240, mid=1456, argc=0, 
argv=0x0, bl_proc=0x555555722460 <inject_i>, 
data2=93825001586200) at vm_eval.c:1142 
1142 { 
(gdb) s 
1145 arg.obj = obj; 
(gdb)
640 rb_block_call_func *iter = inject_i; 
(gdb) n 
665 memo = NEW_MEMO(init, argc, op); 
(gdb) n 
666 rb_block_call(obj, id_each, 0, 0, iter, 
(VALUE)memo); 
(gdb) s 
rb_block_call (obj=93825001586240, mid=1456, argc=0, 
argv=0x0, bl_proc=0x555555722460 <inject_i>, 
data2=93825001586200) at vm_eval.c:1142 
1142 { 
(gdb) s 
1145 arg.obj = obj; 
(gdb) s 
1146 arg.mid = mid; 
(gdb)
640 rb_block_call_func *iter = inject_i; 
(gdb) n 
665 memo = NEW_MEMO(init, argc, op); 
(gdb) n 
666 rb_block_call(obj, id_each, 0, 0, iter, 
(VALUE)memo); 
(gdb) s 
rb_block_call (obj=93825001586240, mid=1456, argc=0, 
argv=0x0, bl_proc=0x555555722460 <inject_i>, 
data2=93825001586200) at vm_eval.c:1142 
1142 { 
(gdb) s 
1145 arg.obj = obj; 
(gdb) s 
1146 arg.mid = mid; 
(gdb) s 
1147 arg.argc = argc; 
(gdb)
(gdb) s 
1147 arg.argc = argc; 
(gdb) s 
1148 arg.argv = argv; 
(gdb)
(gdb) s 
1147 arg.argc = argc; 
(gdb) s 
1148 arg.argv = argv; 
(gdb) s 
1149 return rb_iterate(iterate_method, (VALUE)&arg, 
bl_proc, data2); 
(gdb)
(gdb) s 
1147 arg.argc = argc; 
(gdb) s 
1148 arg.argv = argv; 
(gdb) s 
1149 return rb_iterate(iterate_method, (VALUE)&arg, 
bl_proc, data2); 
(gdb) s 
rb_iterate (it_proc=it_proc@entry=0x5555556c0790 
<iterate_method>, data1=data1@entry=140737488340304, 
bl_proc=0x555555722460 <inject_i>, data2=93825001586200) 
at vm_eval.c:1054 
1054 { 
(gdb)
(gdb) s 
1147 arg.argc = argc; 
(gdb) s 
1148 arg.argv = argv; 
(gdb) s 
1149 return rb_iterate(iterate_method, (VALUE)&arg, 
bl_proc, data2); 
(gdb) s 
rb_iterate (it_proc=it_proc@entry=0x5555556c0790 
<iterate_method>, data1=data1@entry=140737488340304, 
bl_proc=0x555555722460 <inject_i>, data2=93825001586200) 
at vm_eval.c:1054 
1054 { 
(gdb) s 
1057 NODE *node = NEW_IFUNC(bl_proc, data2); 
(gdb)
(gdb) s 
1147 arg.argc = argc; 
(gdb) s 
1148 arg.argv = argv; 
(gdb) s 
1149 return rb_iterate(iterate_method, (VALUE)&arg, 
bl_proc, data2); 
(gdb) s 
rb_iterate (it_proc=it_proc@entry=0x5555556c0790 
<iterate_method>, data1=data1@entry=140737488340304, 
bl_proc=0x555555722460 <inject_i>, data2=93825001586200) 
at vm_eval.c:1054 
1054 { 
(gdb) s 
1057 NODE *node = NEW_IFUNC(bl_proc, data2); 
(gdb)
static VALUE enum_inject(int argc, VALUE *argv, VALUE obj) 
{ 
NODE *memo; 
VALUE init, op; 
rb_block_call_func *iter = inject_i; 
… 
memo = NEW_MEMO(init, argc, op); 
rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); 
return memo->u1.value; 
}
VALUE rb_block_call(…) 
{ 
… 
return rb_iterate(iterate_method, 
(VALUE)&arg, bl_proc, data2); 
} 
VALUE rb_iterate(…) 
{ 
int state; 
volatile VALUE retval = Qnil; 
NODE *node = NEW_IFUNC(bl_proc, data2); 
… 
}
2 T_NODE's per inject() call
10000.times { [].inject } 
20000 extra T_NODE objects 
some work for GC
Ruby 
Performance 
More in my book 
ruby-performance-book.com
Lessons learned: 
1. use profiler to understand why your code is slow 
2. use C debugger to understand Ruby behavior
Example 2
What's the difference? 
str = 'a'*1024*1024*10 
str = str.gsub('a', 'b') 
str = 'a'*1024*1024*10 
str.gsub!('a', 'b')
str = 'a'*1024*1024*10 
str = str.gsub('a', 'b') 
str = 'a'*1024*1024*10 
str.gsub!('a', 'b') 
replaces 'a' with 'b' 
creates a new object 
reuses "str" name 
replaces 'a' with 'b' 
changes the original
Supposedly
Let's profile memory usage 
ruby-prof -p call_tree –mode=memory after.rb > 
callgrind.out.after 
kcachegrind callgrind.out.after
So, gsub! doesn't save any memory
So, gsub! doesn't save any memory 
… except one slot on Ruby heap
So, gsub! doesn't save any memory 
except one slot on Ruby heap 
… which is 40 bytes
Not all bang! functions are the same 
str = 'a'*1024*1024*10 
str.downcase! 
ruby-prof -p call_tree –mode=memory downcase.rb > 
callgrind.out.downcase 
kcachegrind callgrind.out.downcase
Lessons learned: 
1. profile memory 
2. challenge all tips/tricks/best practices
Conclusions 
1. Don't guess. Profile. 
2. Guess. Profile. 
3. Profile not only CPU, but Memory. 
4. Look at the source, use GDB if not enlightened. 
5. Challenge all tips/tricks. Understand instead.
Big thanks to:
Ruby 
Performance 
ruby-performance-book.com 
airpair.me/adymo 
@alexander_dymo

More Related Content

What's hot

Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CSteffen Wenz
 
Start Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New RopeStart Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New RopeYung-Yu Chen
 
Cluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in PracticeCluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in PracticeSteffen Wenz
 
Writing native bindings to node.js in C++
Writing native bindings to node.js in C++Writing native bindings to node.js in C++
Writing native bindings to node.js in C++nsm.nikhil
 
Hacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnHacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnMoriyoshi Koizumi
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersAppier
 
Behavior driven oop
Behavior driven oopBehavior driven oop
Behavior driven oopPiyush Verma
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS EngineChengHui Weng
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Objective-Cひとめぐり
Objective-CひとめぐりObjective-Cひとめぐり
Objective-CひとめぐりKenji Kinukawa
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...DevGAMM Conference
 
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰Jung Kim
 
Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨flyinweb
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
7주 JavaScript 실습
7주 JavaScript 실습7주 JavaScript 실습
7주 JavaScript 실습지수 윤
 
C++totural file
C++totural fileC++totural file
C++totural filehalaisumit
 

What's hot (20)

Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 
Start Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New RopeStart Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New Rope
 
Node.js extensions in C++
Node.js extensions in C++Node.js extensions in C++
Node.js extensions in C++
 
Cluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in PracticeCluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in Practice
 
Writing native bindings to node.js in C++
Writing native bindings to node.js in C++Writing native bindings to node.js in C++
Writing native bindings to node.js in C++
 
Hacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnHacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 Autumn
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python Programmers
 
Groovy.pptx
Groovy.pptxGroovy.pptx
Groovy.pptx
 
Behavior driven oop
Behavior driven oopBehavior driven oop
Behavior driven oop
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Objective-Cひとめぐり
Objective-CひとめぐりObjective-Cひとめぐり
Objective-Cひとめぐり
 
Python Objects
Python ObjectsPython Objects
Python Objects
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
 
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
 
Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
7주 JavaScript 실습
7주 JavaScript 실습7주 JavaScript 실습
7주 JavaScript 실습
 
C++totural file
C++totural fileC++totural file
C++totural file
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 

Viewers also liked

Призма24 - Маркетплейсы.
Призма24 - Маркетплейсы.Призма24 - Маркетплейсы.
Призма24 - Маркетплейсы.Vitalii Tytskyi
 
Debbug Rails Application For Dummies
Debbug Rails Application For DummiesDebbug Rails Application For Dummies
Debbug Rails Application For DummiesAndrey Subbota
 
Deploy.rb, Ilya Zykin, Rails club2016
Deploy.rb, Ilya Zykin, Rails club2016Deploy.rb, Ilya Zykin, Rails club2016
Deploy.rb, Ilya Zykin, Rails club2016zykin-ilya
 
10 reasons I love RubyOnRails
10 reasons I love RubyOnRails10 reasons I love RubyOnRails
10 reasons I love RubyOnRailsPavel Gabriel
 
I18n ruby-приложений
I18n ruby-приложенийI18n ruby-приложений
I18n ruby-приложенийAndrey Sitnik
 
Когда технологий много - iForum 2013
Когда технологий много - iForum 2013Когда технологий много - iForum 2013
Когда технологий много - iForum 2013Andrey Listochkin
 
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo
 
Александр Тищенко - "Антикризисная презентация"
Александр Тищенко - "Антикризисная презентация"Александр Тищенко - "Антикризисная презентация"
Александр Тищенко - "Антикризисная презентация"railsclub
 
Фронтенд для рубиста
Фронтенд для рубистаФронтенд для рубиста
Фронтенд для рубистаKir Shatrov
 
развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)guest40e031
 
Как сделать контрибут в Ruby on Rails
Как сделать контрибут в Ruby on RailsКак сделать контрибут в Ruby on Rails
Как сделать контрибут в Ruby on RailsYaroslav Markin
 

Viewers also liked (20)

Profiling Ruby
Profiling RubyProfiling Ruby
Profiling Ruby
 
Призма24 - Маркетплейсы.
Призма24 - Маркетплейсы.Призма24 - Маркетплейсы.
Призма24 - Маркетплейсы.
 
Debbug Rails Application For Dummies
Debbug Rails Application For DummiesDebbug Rails Application For Dummies
Debbug Rails Application For Dummies
 
RSpec. Part 2
RSpec. Part 2RSpec. Part 2
RSpec. Part 2
 
R18n
R18nR18n
R18n
 
Deploy.rb, Ilya Zykin, Rails club2016
Deploy.rb, Ilya Zykin, Rails club2016Deploy.rb, Ilya Zykin, Rails club2016
Deploy.rb, Ilya Zykin, Rails club2016
 
10 reasons I love RubyOnRails
10 reasons I love RubyOnRails10 reasons I love RubyOnRails
10 reasons I love RubyOnRails
 
RSpec. Part 3
RSpec. Part 3RSpec. Part 3
RSpec. Part 3
 
I18n ruby-приложений
I18n ruby-приложенийI18n ruby-приложений
I18n ruby-приложений
 
Rails Concerns
Rails ConcernsRails Concerns
Rails Concerns
 
Ruby on Rails for noobs
Ruby on Rails for noobsRuby on Rails for noobs
Ruby on Rails for noobs
 
Когда технологий много - iForum 2013
Когда технологий много - iForum 2013Когда технологий много - iForum 2013
Когда технологий много - iForum 2013
 
Assets Pipeline
Assets PipelineAssets Pipeline
Assets Pipeline
 
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
 
Александр Тищенко - "Антикризисная презентация"
Александр Тищенко - "Антикризисная презентация"Александр Тищенко - "Антикризисная презентация"
Александр Тищенко - "Антикризисная презентация"
 
Фронтенд для рубиста
Фронтенд для рубистаФронтенд для рубиста
Фронтенд для рубиста
 
RSpec. Part 1
RSpec. Part 1RSpec. Part 1
RSpec. Part 1
 
развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)развертывание среды Rails (антон веснин, Locum Ru)
развертывание среды Rails (антон веснин, Locum Ru)
 
Как сделать контрибут в Ruby on Rails
Как сделать контрибут в Ruby on RailsКак сделать контрибут в Ruby on Rails
Как сделать контрибут в Ruby on Rails
 
Why does code style matter?
Why does code style matter?Why does code style matter?
Why does code style matter?
 

Similar to Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover Them

Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby CoreHiroshi SHIBATA
 
mruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしmruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしHiroshi SHIBATA
 
Vc4c development of opencl compiler for videocore4
Vc4c  development of opencl compiler for videocore4Vc4c  development of opencl compiler for videocore4
Vc4c development of opencl compiler for videocore4nomaddo
 
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012rivierarb
 
2.1 ### uVision Project, (C) Keil Software .docx
2.1   ### uVision Project, (C) Keil Software    .docx2.1   ### uVision Project, (C) Keil Software    .docx
2.1 ### uVision Project, (C) Keil Software .docxtarifarmarie
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
05 - Bypassing DEP, or why ASLR matters
05 - Bypassing DEP, or why ASLR matters05 - Bypassing DEP, or why ASLR matters
05 - Bypassing DEP, or why ASLR mattersAlexandre Moneger
 
Catch a spider monkey
Catch a spider monkeyCatch a spider monkey
Catch a spider monkeyChengHui Weng
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHiroshi SHIBATA
 
Performance Wins with BPF: Getting Started
Performance Wins with BPF: Getting StartedPerformance Wins with BPF: Getting Started
Performance Wins with BPF: Getting StartedBrendan Gregg
 
Otimizando Aplicações em Rails
Otimizando Aplicações em RailsOtimizando Aplicações em Rails
Otimizando Aplicações em RailsJuan Maiz
 
Gdb basics for my sql db as (openfest 2017) final
Gdb basics for my sql db as (openfest 2017) finalGdb basics for my sql db as (openfest 2017) final
Gdb basics for my sql db as (openfest 2017) finalValeriy Kravchuk
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays
 
More on gdb for my sql db as (fosdem 2016)
More on gdb for my sql db as (fosdem 2016)More on gdb for my sql db as (fosdem 2016)
More on gdb for my sql db as (fosdem 2016)Valeriy Kravchuk
 
The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.5.4 book - Part 81 of 185The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.5.4 book - Part 81 of 185Mahmoud Samir Fayed
 
Web aplikāciju izstrāde ar Ruby on Rails un Oracle DB
Web aplikāciju izstrāde ar Ruby on Rails un Oracle DBWeb aplikāciju izstrāde ar Ruby on Rails un Oracle DB
Web aplikāciju izstrāde ar Ruby on Rails un Oracle DBRaimonds Simanovskis
 
Command Line Applications with Ruby
Command Line Applications with RubyCommand Line Applications with Ruby
Command Line Applications with RubyAlexander Merkulov
 
Linux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloudLinux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloudAndrea Righi
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbJuan Maiz
 

Similar to Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover Them (20)

Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
mruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしmruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなし
 
Vc4c development of opencl compiler for videocore4
Vc4c  development of opencl compiler for videocore4Vc4c  development of opencl compiler for videocore4
Vc4c development of opencl compiler for videocore4
 
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
 
2.1 ### uVision Project, (C) Keil Software .docx
2.1   ### uVision Project, (C) Keil Software    .docx2.1   ### uVision Project, (C) Keil Software    .docx
2.1 ### uVision Project, (C) Keil Software .docx
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
05 - Bypassing DEP, or why ASLR matters
05 - Bypassing DEP, or why ASLR matters05 - Bypassing DEP, or why ASLR matters
05 - Bypassing DEP, or why ASLR matters
 
Catch a spider monkey
Catch a spider monkeyCatch a spider monkey
Catch a spider monkey
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby Core
 
Performance Wins with BPF: Getting Started
Performance Wins with BPF: Getting StartedPerformance Wins with BPF: Getting Started
Performance Wins with BPF: Getting Started
 
Otimizando Aplicações em Rails
Otimizando Aplicações em RailsOtimizando Aplicações em Rails
Otimizando Aplicações em Rails
 
Gdb basics for my sql db as (openfest 2017) final
Gdb basics for my sql db as (openfest 2017) finalGdb basics for my sql db as (openfest 2017) final
Gdb basics for my sql db as (openfest 2017) final
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
 
More on gdb for my sql db as (fosdem 2016)
More on gdb for my sql db as (fosdem 2016)More on gdb for my sql db as (fosdem 2016)
More on gdb for my sql db as (fosdem 2016)
 
The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.5.4 book - Part 81 of 185The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.5.4 book - Part 81 of 185
 
Hybrid Tips & Tricks
Hybrid Tips & TricksHybrid Tips & Tricks
Hybrid Tips & Tricks
 
Web aplikāciju izstrāde ar Ruby on Rails un Oracle DB
Web aplikāciju izstrāde ar Ruby on Rails un Oracle DBWeb aplikāciju izstrāde ar Ruby on Rails un Oracle DB
Web aplikāciju izstrāde ar Ruby on Rails un Oracle DB
 
Command Line Applications with Ruby
Command Line Applications with RubyCommand Line Applications with Ruby
Command Line Applications with Ruby
 
Linux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloudLinux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloud
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRb
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 

Recently uploaded (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 

Alexander Dymo - RubyConf 2014 - Ruby Performance Secrets and How to Uncover Them

  • 1. Ruby Performance Secrets and How to Uncover Them http://www.slideshare.net/adymo/adymo-rubyconf-performance
  • 2. Who am I? Alexander Dymo C/C++ since 2000 Ruby/Rails since 2006 Started to optimize back in 2007 Never stopped since then
  • 3. Rails Performance: What You Need to Know https://www.airpair.com/ruby-on-rails/performance Make Your Ruby/Rails App Fast: Performance And Memory Profiling Using ruby-prof and Kcachegrind http://www.acunote.com/blog/2008/02/make-your-ruby-rails-applications-fast-performance-and-memory-profiling.html Ruby Performance Tuning http://theprosegarden.com/contents-of-recent-issues/#10-14
  • 4. Ruby Performance The first comprehensive book on Ruby Performance I'm 50% done. Beta soon. ruby-performance-book.com
  • 6. What do we talk about today? Performance tips Performance best practices
  • 7. What do we talk about today? Performance tips Performance best practices How to understand what's wrong How to find your own performance tips/best practices
  • 10. What can go wrong with this code?
  • 11. What can go wrong with this code?
  • 13.
  • 17. Let's check what happens:
  • 18. Let's profile memory allocations Need patched ruby rvm reinstall 1.9.3 --patch railsexpress rvm reinstall 2.0.0 --patch railsexpress rvm reinstall 2.1.4 --patch railsexpress
  • 19. Let's profile memory allocations Need profiler gem install ruby-prof
  • 20. Let's profile memory allocations Need visualization tool Mac: brew install qcachegrind Linux: <your package manager> install kcachegrind Windows: http://sourceforge.net/projects/qcachegrindwin/
  • 21. Let's profile memory allocations ruby-prof -p call_tree –mode=allocations before.rb > callgrind.out.before ruby-prof -p call_tree –mode=allocations after.rb > callgrind.out.after kcachegrind callgrind.out.before kcachegrind callgrind.out.after
  • 22.
  • 23.
  • 24.
  • 25. static VALUE enum_inject(int argc, VALUE *argv, VALUE obj) { NODE *memo; VALUE init, op; rb_block_call_func *iter = inject_i; … memo = NEW_MEMO(init, argc, op); rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); return memo->u1.value; }
  • 26. > gdb `rbenv which ruby` GNU gdb (GDB) SUSE (7.5.1-2.5.1) Reading symbols from /home/gremlin/.rbenv/versions/2.1.4/bin/ruby...done. (gdb)
  • 27. (gdb) l enum_inject 632 * longest #=> "sheep" 633 * 634 */ 635 static VALUE 636 enum_inject(int argc, VALUE *argv, VALUE obj) 637 { 638 NODE *memo; 639 VALUE init, op; 640 rb_block_call_func *iter = inject_i; 641 ID id; (gdb)
  • 28. 636 enum_inject(int argc, VALUE *argv, VALUE obj) 637 { 638 NODE *memo; 639 VALUE init, op; 640 rb_block_call_func *iter = inject_i; 641 ID id; (gdb) b 638 Breakpoint 1 at 0x1cbc0a: file enum.c, line 638. (gdb)
  • 29. (gdb) r -e '[1,2,3].inject {}' Starting program: /home/gremlin/.rbenv/versions/2.1.4/bin/ruby -e '[1,2,3].inject {}' [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". [New Thread 0x7ffff7ff2700 (LWP 3893)] Breakpoint 1, enum_inject (argc=0, argv=<optimized out>, obj=93825001586240) at enum.c:640 640 rb_block_call_func *iter = inject_i; (gdb)
  • 30. 640 rb_block_call_func *iter = inject_i; (gdb) n 665 memo = NEW_MEMO(init, argc, op); (gdb)
  • 31. 640 rb_block_call_func *iter = inject_i; (gdb) n 665 memo = NEW_MEMO(init, argc, op); (gdb) n 666 rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); (gdb)
  • 32. 640 rb_block_call_func *iter = inject_i; (gdb) n 665 memo = NEW_MEMO(init, argc, op); (gdb) n 666 rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); (gdb) s rb_block_call (obj=93825001586240, mid=1456, argc=0, argv=0x0, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1142 1142 { (gdb)
  • 33. 640 rb_block_call_func *iter = inject_i; (gdb) n 665 memo = NEW_MEMO(init, argc, op); (gdb) n 666 rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); (gdb) s rb_block_call (obj=93825001586240, mid=1456, argc=0, argv=0x0, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1142 1142 { (gdb) s 1145 arg.obj = obj; (gdb)
  • 34. 640 rb_block_call_func *iter = inject_i; (gdb) n 665 memo = NEW_MEMO(init, argc, op); (gdb) n 666 rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); (gdb) s rb_block_call (obj=93825001586240, mid=1456, argc=0, argv=0x0, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1142 1142 { (gdb) s 1145 arg.obj = obj; (gdb) s 1146 arg.mid = mid; (gdb)
  • 35. 640 rb_block_call_func *iter = inject_i; (gdb) n 665 memo = NEW_MEMO(init, argc, op); (gdb) n 666 rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); (gdb) s rb_block_call (obj=93825001586240, mid=1456, argc=0, argv=0x0, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1142 1142 { (gdb) s 1145 arg.obj = obj; (gdb) s 1146 arg.mid = mid; (gdb) s 1147 arg.argc = argc; (gdb)
  • 36. (gdb) s 1147 arg.argc = argc; (gdb) s 1148 arg.argv = argv; (gdb)
  • 37. (gdb) s 1147 arg.argc = argc; (gdb) s 1148 arg.argv = argv; (gdb) s 1149 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); (gdb)
  • 38. (gdb) s 1147 arg.argc = argc; (gdb) s 1148 arg.argv = argv; (gdb) s 1149 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); (gdb) s rb_iterate (it_proc=it_proc@entry=0x5555556c0790 <iterate_method>, data1=data1@entry=140737488340304, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1054 1054 { (gdb)
  • 39. (gdb) s 1147 arg.argc = argc; (gdb) s 1148 arg.argv = argv; (gdb) s 1149 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); (gdb) s rb_iterate (it_proc=it_proc@entry=0x5555556c0790 <iterate_method>, data1=data1@entry=140737488340304, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1054 1054 { (gdb) s 1057 NODE *node = NEW_IFUNC(bl_proc, data2); (gdb)
  • 40. (gdb) s 1147 arg.argc = argc; (gdb) s 1148 arg.argv = argv; (gdb) s 1149 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); (gdb) s rb_iterate (it_proc=it_proc@entry=0x5555556c0790 <iterate_method>, data1=data1@entry=140737488340304, bl_proc=0x555555722460 <inject_i>, data2=93825001586200) at vm_eval.c:1054 1054 { (gdb) s 1057 NODE *node = NEW_IFUNC(bl_proc, data2); (gdb)
  • 41. static VALUE enum_inject(int argc, VALUE *argv, VALUE obj) { NODE *memo; VALUE init, op; rb_block_call_func *iter = inject_i; … memo = NEW_MEMO(init, argc, op); rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo); return memo->u1.value; }
  • 42. VALUE rb_block_call(…) { … return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); } VALUE rb_iterate(…) { int state; volatile VALUE retval = Qnil; NODE *node = NEW_IFUNC(bl_proc, data2); … }
  • 43. 2 T_NODE's per inject() call
  • 44. 10000.times { [].inject } 20000 extra T_NODE objects some work for GC
  • 45.
  • 46. Ruby Performance More in my book ruby-performance-book.com
  • 47. Lessons learned: 1. use profiler to understand why your code is slow 2. use C debugger to understand Ruby behavior
  • 49. What's the difference? str = 'a'*1024*1024*10 str = str.gsub('a', 'b') str = 'a'*1024*1024*10 str.gsub!('a', 'b')
  • 50. str = 'a'*1024*1024*10 str = str.gsub('a', 'b') str = 'a'*1024*1024*10 str.gsub!('a', 'b') replaces 'a' with 'b' creates a new object reuses "str" name replaces 'a' with 'b' changes the original
  • 52. Let's profile memory usage ruby-prof -p call_tree –mode=memory after.rb > callgrind.out.after kcachegrind callgrind.out.after
  • 53.
  • 54. So, gsub! doesn't save any memory
  • 55. So, gsub! doesn't save any memory … except one slot on Ruby heap
  • 56. So, gsub! doesn't save any memory except one slot on Ruby heap … which is 40 bytes
  • 57. Not all bang! functions are the same str = 'a'*1024*1024*10 str.downcase! ruby-prof -p call_tree –mode=memory downcase.rb > callgrind.out.downcase kcachegrind callgrind.out.downcase
  • 58.
  • 59. Lessons learned: 1. profile memory 2. challenge all tips/tricks/best practices
  • 60. Conclusions 1. Don't guess. Profile. 2. Guess. Profile. 3. Profile not only CPU, but Memory. 4. Look at the source, use GDB if not enlightened. 5. Challenge all tips/tricks. Understand instead.
  • 62. Ruby Performance ruby-performance-book.com airpair.me/adymo @alexander_dymo