SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Andere mochten auch

Призма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
 

Andere mochten auch (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?
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Kürzlich hochgeladen

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
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.
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
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
 
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.
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
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
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 

Kürzlich hochgeladen (20)

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
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 ...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
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
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
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
 
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
 
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...
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
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 ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 

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