SlideShare uma empresa Scribd logo
1 de 45
Improve Performance Quick and Cheap:
Optimize Memory and Upgrade to Ruby 2.1
http://www.slideshare.net/adymo/adymo-railsconf-improveperformance
Part 1
Why?
Memory optimization is the #1 thing that
makes your Ruby application fast
Memory overhead
+
Slow GC algorithm
=
Memory overhead
+
Slow GC algorithm
=
High memory consumption
+
Enormous time spent in GC
2010 2011 2012 2013 2014
0
5
10
15
20
25
Requests(millions)
Memory Optimized Rails App (Ruby 1.8)
Same $1k/mo hardware all these years
Rails App Upgraded from Ruby 1.9 to 2.1
Compare before/after
Optimize Memory and
Optionally
Upgrade to Ruby 2.1
require "csv"
data = CSV.open("data.csv")
output = data.readlines.map do |line|
line.map do |col|
col.downcase.gsub(/b('?[a-z])/) { $1.capitalize } }
end
end
File.open("output.csv", "w+") do |f|
f.write output.join("n")
end
Unoptimized Program
Ruby 1.9 & 2.0
Ruby 2.1
0 5 10 15 20 25
Ruby 2.1 Is 40% Faster, Right?
require "csv"
output = File.open("output.csv", "w+")
CSV.open("examples/data.csv", "r").each do |line|
output.puts line.map do |col|
col.downcase!
col.gsub!(/b('?[a-z])/) { $1.capitalize! }
end.join(",")
end
Memory Optimized Program
Ruby 2.1 Is NOT Faster
...once your program is memory optimized
Ruby 1.9 & 2.0
Ruby 2.1
0 2 4 6 8 10 12 14
Takeaways
1. Ruby 2.1 is not a silver performance bullet
2. Memory optimized Ruby app performs the same in 1.9, 2.0 and 2.1
3. Ruby 2.1 merely makes performance adequate by default
4. Optimize memory to make a difference
Part 2
How?
5 Memory Optimization Strategies
1. Tune garbage collector
2. Do not allow Ruby instance to grow
3. Control GC manually
4. Write less Ruby
5. Avoid memory-intensive Ruby and Rails features
Strategy 1
Tune Ruby GC
Ruby GC Tuning Goal
Goal: balance the number of GC runs and peak memory usage
How to check:
> GC.stat[:minor_gc_count]
> GC.stat[:major_gc_count]
> `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024 #MB
When Is Ruby GC Triggered?
Minor GC (faster, only new objects collected):
- not enough space on the Ruby heap to allocate new objects
- every 16MB-32MB of memory allocated in new objects
Major GC (slower, all objects collected):
- number of old or shady objects increases more than 2x
- every 16MB-128MB of memory allocated in old objects
Environment Variables
Initial number of slots on the heap RUBY_GC_HEAP_INIT_SLOTS 1000
Min number of slots that GC must free RUBY_GC_HEAP_FREE_SLOTS 4096
Heap growth factor RUBY_GC_HEAP_GROWTH_FACTOR 1.8
Maximum heap slots to add RUBY_GC_HEAP_GROWTH_MAX_SLOTS -
New generation malloc limit RUBY_GC_MALLOC_LIMIT 16M
Maximum new generation malloc limit RUBY_GC_MALLOC_LIMIT_MAX 32M
New generation malloc growth factor RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR 1.4
Old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT 16M
Maximum old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT_MAX 128M
Old generation malloc growth factor RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR 1.2
When Is Ruby GC Triggered?
ruby-performance-book.com
http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc
http://thorstenball.com/blog/2014/03/12/watching-understanding-ruby-2.1-garbage-collector/
Strategy 2
Limit Growth
3 Layers of Memory Consumption Control
1. Internal
read `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024
or VmRSS from/proc/pid/#{Process.pid}
and exit worker
3 Layers of Memory Consumption Control
1. Internal
read `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024
or VmRSS from/proc/pid/#{Process.pid}
and exit worker
3 Layers of Memory Consumption Control
2. External (software)
Heroku, Monit, God, etc.
3 Layers of Memory Consumption Control
3. External (OS kernel)
Process.setrlimit(Process::RLIMIT_AS, <N bytes>)
What about Background Jobs?
Fork et Impera:
# setup background job
fork do
# do something heavy
end
Strategy 3
Control GC Manually
GC Between Requests in Unicorn
OobGC for Ruby < 2.1
require 'unicorn/oob_gc'
use(Unicorn::OobGC, 1)
gctools for Ruby >= 2.1 https://github.com/tmm1/gctools
require 'gctools/oobgc'
use(GC::OOB::UnicornMiddleware)
GC Between Requests in Unicorn
Things to have in mind:
- make sure you have enough workers
- make sure CPU utilization < 50%
- this improves only “perceived” performance
- overall performance might be worse
- only effective for memory-intensive applications
Strategy 4
Write Less Ruby
Example: Group Rank
SELECT * FROM empsalary;
depname | empno | salary
-----------+-------+-------
develop | 6 | 6000
develop | 7 | 4500
develop | 5 | 4200
personnel | 2 | 3900
personnel | 4 | 3500
sales | 1 | 5000
sales | 3 | 4800
PostgreSQL Window Functions
SELECT depname, empno, salary, rank()
OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
depname | empno | salary | rank
-----------+-------+--------+------
develop | 6 | 6000 | 1
develop | 7 | 4500 | 2
develop | 5 | 4200 | 3
personnel | 2 | 3900 | 1
personnel | 4 | 3500 | 2
sales | 1 | 5000 | 1
sales | 3 | 4800 | 2
Finally Learn SQL
Strategy 5
Avoid Memory Hogs
Operations That Copy Data
● String::gsub! instead of String::gsub and similar
● String::<< instead of String::+=
● File::readline or File::each instead of File::readlines or File.read
● CSV::parseline instead of CSV::parse
ActiveRecord Also Copies Data
● ActiveRecord::Base::update_all
Book.where('title LIKE ?', '%Rails%').
order(:created_at).limit(5).
update_all(author: 'David')
● Direct manipulation over query result
result = ActiveRecord::Base.execute 'select * from books'
result.each do |row|
# do something with row.values_at('col1', 'col2')
end
Rails Serializers Copy Too Much
class Smth < ActiveRecord::Base
serialize :data, JSON
end
class Smth < ActiveRecord::Base
def data
JSON.parse(read_attribute(:data))
end
def data=(value)
write_attribute(:data, value.to_json)
end
end
Part 3
Tools
GC.stat
=>{
:count=>11,
:minor_gc_count=>8,
:major_gc_count=>3,
:heap_used=>126,
:heap_length=>130,
:malloc_increase=>7848,
:malloc_limit=>16777216,
:oldmalloc_increase=>8296,
:oldmalloc_limit=>16777216
}
objspace.so
> ObjectSpace.count_objects
=> {:TOTAL=>51359, :FREE=>16314, :T_OBJECT=>1356 ...
> require 'objspace'
> ObjectSpace.memsize_of(Class)
=> 1096
> ObjectSpace.reachable_objects_from(Class)
=> [#<InternalObject:0x007f87acf06e10 T_CLASS>, Class...
> ObjectSpace.trace_object_allocations_start
> str = "x" * 1024 * 1024 * 10
> ObjectSpace.allocation_generation(str)
=> 11
objspace.so
http://tmm1.net/ruby21-objspace/
http://stackoverflow.com/q/20956401
GC.stat
http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc
RubyProf Memory Profiling
require 'ruby-prof'
RubyProf.measure_mode = RubyProf::MEMORY
RubyProf.start
str = 'x'*1024*1024*10
result = RubyProf.stop
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
This requires patched Ruby, will work only for 1.8 and 1.9
https://github.com/ruby-prof/ruby-prof/issues/86
Valgrind Memory Profiling
> valgrind --tool=massif `rbenv which irb`
==9395== Massif, a heap profiler
irb(main):001:0> x = "x"*1024*1024*10; nil
=> nil
==9395==
> ms_print massif.out.9395
> massif-visualizer massif.out.9395
http://valgrind.org
https://projects.kde.org/projects/extragear/sdk/massif-visualizer
http://www.slideshare.net/adymo/adymo-railsconf-improveperformance
Sign up for my upcoming book updates:
ruby-performance-book.com
Ask me:
alex@alexdymo.com
@alexander_dymo
AirPair with me:
airpair.me/adymo

Mais conteúdo relacionado

Mais procurados

Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit
 
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit
 

Mais procurados (20)

Vertica mpp columnar dbms
Vertica mpp columnar dbmsVertica mpp columnar dbms
Vertica mpp columnar dbms
 
Vertica architecture
Vertica architectureVertica architecture
Vertica architecture
 
Scio - A Scala API for Google Cloud Dataflow & Apache Beam
Scio - A Scala API for Google Cloud Dataflow & Apache BeamScio - A Scala API for Google Cloud Dataflow & Apache Beam
Scio - A Scala API for Google Cloud Dataflow & Apache Beam
 
SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)
 
PostgreSQL on AWS: Tips & Tricks (and horror stories)
PostgreSQL on AWS: Tips & Tricks (and horror stories)PostgreSQL on AWS: Tips & Tricks (and horror stories)
PostgreSQL on AWS: Tips & Tricks (and horror stories)
 
How to performance tune spark applications in large clusters
How to performance tune spark applications in large clustersHow to performance tune spark applications in large clusters
How to performance tune spark applications in large clusters
 
Shipping Data from Postgres to Clickhouse, by Murat Kabilov, Adjust
Shipping Data from Postgres to Clickhouse, by Murat Kabilov, AdjustShipping Data from Postgres to Clickhouse, by Murat Kabilov, Adjust
Shipping Data from Postgres to Clickhouse, by Murat Kabilov, Adjust
 
Data profiling in Apache Calcite
Data profiling in Apache CalciteData profiling in Apache Calcite
Data profiling in Apache Calcite
 
How Adobe Does 2 Million Records Per Second Using Apache Spark!
How Adobe Does 2 Million Records Per Second Using Apache Spark!How Adobe Does 2 Million Records Per Second Using Apache Spark!
How Adobe Does 2 Million Records Per Second Using Apache Spark!
 
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
 
RDFox Poster
RDFox PosterRDFox Poster
RDFox Poster
 
Upgrading To The New Map Reduce API
Upgrading To The New Map Reduce APIUpgrading To The New Map Reduce API
Upgrading To The New Map Reduce API
 
HBaseCon2017 Quanta: Quora's hierarchical counting system on HBase
HBaseCon2017 Quanta: Quora's hierarchical counting system on HBaseHBaseCon2017 Quanta: Quora's hierarchical counting system on HBase
HBaseCon2017 Quanta: Quora's hierarchical counting system on HBase
 
Prediction as a service with ensemble model in SparkML and Python ScikitLearn
Prediction as a service with ensemble model in SparkML and Python ScikitLearnPrediction as a service with ensemble model in SparkML and Python ScikitLearn
Prediction as a service with ensemble model in SparkML and Python ScikitLearn
 
S3, Cassandra or Outer Space? Dumping Time Series Data using Spark - Demi Ben...
S3, Cassandra or Outer Space? Dumping Time Series Data using Spark - Demi Ben...S3, Cassandra or Outer Space? Dumping Time Series Data using Spark - Demi Ben...
S3, Cassandra or Outer Space? Dumping Time Series Data using Spark - Demi Ben...
 
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
 
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
 
Apache Sqoop: A Data Transfer Tool for Hadoop
Apache Sqoop: A Data Transfer Tool for HadoopApache Sqoop: A Data Transfer Tool for Hadoop
Apache Sqoop: A Data Transfer Tool for Hadoop
 
Audience counting at Scale
Audience counting at ScaleAudience counting at Scale
Audience counting at Scale
 
Adventures in Observability: How in-house ClickHouse deployment enabled Inst...
 Adventures in Observability: How in-house ClickHouse deployment enabled Inst... Adventures in Observability: How in-house ClickHouse deployment enabled Inst...
Adventures in Observability: How in-house ClickHouse deployment enabled Inst...
 

Semelhante a Alexander Dymo - RailsConf 2014 - Improve performance: Optimize Memory and Upgrade to Ruby 2.1

Handling 20 billion requests a month
Handling 20 billion requests a monthHandling 20 billion requests a month
Handling 20 billion requests a month
Dmitriy Dumanskiy
 

Semelhante a Alexander Dymo - RailsConf 2014 - Improve performance: Optimize Memory and Upgrade to Ruby 2.1 (20)

Enterprise application performance - Understanding & Learnings
Enterprise application performance - Understanding & LearningsEnterprise application performance - Understanding & Learnings
Enterprise application performance - Understanding & Learnings
 
Cold fusion is racecar fast
Cold fusion is racecar fastCold fusion is racecar fast
Cold fusion is racecar fast
 
Debugging Memory Problems in Rails
Debugging Memory Problems in RailsDebugging Memory Problems in Rails
Debugging Memory Problems in Rails
 
Handling 20 billion requests a month
Handling 20 billion requests a monthHandling 20 billion requests a month
Handling 20 billion requests a month
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
 
Jvm Performance Tunning
Jvm Performance TunningJvm Performance Tunning
Jvm Performance Tunning
 
Jvm Performance Tunning
Jvm Performance TunningJvm Performance Tunning
Jvm Performance Tunning
 
DevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on KubernetesDevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on Kubernetes
 
Tweaking performance on high-load projects
Tweaking performance on high-load projectsTweaking performance on high-load projects
Tweaking performance on high-load projects
 
(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features
(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features
(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features
 
Performance tuning jvm
Performance tuning jvmPerformance tuning jvm
Performance tuning jvm
 
Java 어플리케이션 성능튜닝 Part1
Java 어플리케이션 성능튜닝 Part1Java 어플리케이션 성능튜닝 Part1
Java 어플리케이션 성능튜닝 Part1
 
Hadoop Summit Amsterdam 2014: Capacity Planning In Multi-tenant Hadoop Deploy...
Hadoop Summit Amsterdam 2014: Capacity Planning In Multi-tenant Hadoop Deploy...Hadoop Summit Amsterdam 2014: Capacity Planning In Multi-tenant Hadoop Deploy...
Hadoop Summit Amsterdam 2014: Capacity Planning In Multi-tenant Hadoop Deploy...
 
State of Java Elasticity. Tuning Java Efficiency - GIDS.JAVA LIVE 2020
State of Java Elasticity. Tuning Java Efficiency - GIDS.JAVA LIVE 2020State of Java Elasticity. Tuning Java Efficiency - GIDS.JAVA LIVE 2020
State of Java Elasticity. Tuning Java Efficiency - GIDS.JAVA LIVE 2020
 
JVM and OS Tuning for accelerating Spark application
JVM and OS Tuning for accelerating Spark applicationJVM and OS Tuning for accelerating Spark application
JVM and OS Tuning for accelerating Spark application
 
Tweaking perfomance on high-load projects_Думанский Дмитрий
Tweaking perfomance on high-load projects_Думанский ДмитрийTweaking perfomance on high-load projects_Думанский Дмитрий
Tweaking perfomance on high-load projects_Думанский Дмитрий
 
Toronto meetup 20190917
Toronto meetup 20190917Toronto meetup 20190917
Toronto meetup 20190917
 
Ruby memory tips and tricks
Ruby memory tips and tricksRuby memory tips and tricks
Ruby memory tips and tricks
 
Big data should be simple
Big data should be simpleBig data should be simple
Big data should be simple
 
millions-gc-jax-2022.pptx
millions-gc-jax-2022.pptxmillions-gc-jax-2022.pptx
millions-gc-jax-2022.pptx
 

Último

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Último (20)

AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 

Alexander Dymo - RailsConf 2014 - Improve performance: Optimize Memory and Upgrade to Ruby 2.1

  • 1. Improve Performance Quick and Cheap: Optimize Memory and Upgrade to Ruby 2.1 http://www.slideshare.net/adymo/adymo-railsconf-improveperformance
  • 3. Memory optimization is the #1 thing that makes your Ruby application fast
  • 5. Memory overhead + Slow GC algorithm = High memory consumption + Enormous time spent in GC
  • 6. 2010 2011 2012 2013 2014 0 5 10 15 20 25 Requests(millions) Memory Optimized Rails App (Ruby 1.8) Same $1k/mo hardware all these years
  • 7. Rails App Upgraded from Ruby 1.9 to 2.1 Compare before/after
  • 9. require "csv" data = CSV.open("data.csv") output = data.readlines.map do |line| line.map do |col| col.downcase.gsub(/b('?[a-z])/) { $1.capitalize } } end end File.open("output.csv", "w+") do |f| f.write output.join("n") end Unoptimized Program
  • 10. Ruby 1.9 & 2.0 Ruby 2.1 0 5 10 15 20 25 Ruby 2.1 Is 40% Faster, Right?
  • 11. require "csv" output = File.open("output.csv", "w+") CSV.open("examples/data.csv", "r").each do |line| output.puts line.map do |col| col.downcase! col.gsub!(/b('?[a-z])/) { $1.capitalize! } end.join(",") end Memory Optimized Program
  • 12. Ruby 2.1 Is NOT Faster ...once your program is memory optimized Ruby 1.9 & 2.0 Ruby 2.1 0 2 4 6 8 10 12 14
  • 13. Takeaways 1. Ruby 2.1 is not a silver performance bullet 2. Memory optimized Ruby app performs the same in 1.9, 2.0 and 2.1 3. Ruby 2.1 merely makes performance adequate by default 4. Optimize memory to make a difference
  • 15. 5 Memory Optimization Strategies 1. Tune garbage collector 2. Do not allow Ruby instance to grow 3. Control GC manually 4. Write less Ruby 5. Avoid memory-intensive Ruby and Rails features
  • 17. Ruby GC Tuning Goal Goal: balance the number of GC runs and peak memory usage How to check: > GC.stat[:minor_gc_count] > GC.stat[:major_gc_count] > `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024 #MB
  • 18. When Is Ruby GC Triggered? Minor GC (faster, only new objects collected): - not enough space on the Ruby heap to allocate new objects - every 16MB-32MB of memory allocated in new objects Major GC (slower, all objects collected): - number of old or shady objects increases more than 2x - every 16MB-128MB of memory allocated in old objects
  • 19. Environment Variables Initial number of slots on the heap RUBY_GC_HEAP_INIT_SLOTS 1000 Min number of slots that GC must free RUBY_GC_HEAP_FREE_SLOTS 4096 Heap growth factor RUBY_GC_HEAP_GROWTH_FACTOR 1.8 Maximum heap slots to add RUBY_GC_HEAP_GROWTH_MAX_SLOTS - New generation malloc limit RUBY_GC_MALLOC_LIMIT 16M Maximum new generation malloc limit RUBY_GC_MALLOC_LIMIT_MAX 32M New generation malloc growth factor RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR 1.4 Old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT 16M Maximum old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT_MAX 128M Old generation malloc growth factor RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR 1.2
  • 20. When Is Ruby GC Triggered? ruby-performance-book.com http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc http://thorstenball.com/blog/2014/03/12/watching-understanding-ruby-2.1-garbage-collector/
  • 22. 3 Layers of Memory Consumption Control 1. Internal read `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024 or VmRSS from/proc/pid/#{Process.pid} and exit worker
  • 23. 3 Layers of Memory Consumption Control 1. Internal read `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024 or VmRSS from/proc/pid/#{Process.pid} and exit worker
  • 24. 3 Layers of Memory Consumption Control 2. External (software) Heroku, Monit, God, etc.
  • 25. 3 Layers of Memory Consumption Control 3. External (OS kernel) Process.setrlimit(Process::RLIMIT_AS, <N bytes>)
  • 26. What about Background Jobs? Fork et Impera: # setup background job fork do # do something heavy end
  • 28. GC Between Requests in Unicorn OobGC for Ruby < 2.1 require 'unicorn/oob_gc' use(Unicorn::OobGC, 1) gctools for Ruby >= 2.1 https://github.com/tmm1/gctools require 'gctools/oobgc' use(GC::OOB::UnicornMiddleware)
  • 29. GC Between Requests in Unicorn Things to have in mind: - make sure you have enough workers - make sure CPU utilization < 50% - this improves only “perceived” performance - overall performance might be worse - only effective for memory-intensive applications
  • 31. Example: Group Rank SELECT * FROM empsalary; depname | empno | salary -----------+-------+------- develop | 6 | 6000 develop | 7 | 4500 develop | 5 | 4200 personnel | 2 | 3900 personnel | 4 | 3500 sales | 1 | 5000 sales | 3 | 4800
  • 32. PostgreSQL Window Functions SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary; depname | empno | salary | rank -----------+-------+--------+------ develop | 6 | 6000 | 1 develop | 7 | 4500 | 2 develop | 5 | 4200 | 3 personnel | 2 | 3900 | 1 personnel | 4 | 3500 | 2 sales | 1 | 5000 | 1 sales | 3 | 4800 | 2
  • 35. Operations That Copy Data ● String::gsub! instead of String::gsub and similar ● String::<< instead of String::+= ● File::readline or File::each instead of File::readlines or File.read ● CSV::parseline instead of CSV::parse
  • 36. ActiveRecord Also Copies Data ● ActiveRecord::Base::update_all Book.where('title LIKE ?', '%Rails%'). order(:created_at).limit(5). update_all(author: 'David') ● Direct manipulation over query result result = ActiveRecord::Base.execute 'select * from books' result.each do |row| # do something with row.values_at('col1', 'col2') end
  • 37. Rails Serializers Copy Too Much class Smth < ActiveRecord::Base serialize :data, JSON end class Smth < ActiveRecord::Base def data JSON.parse(read_attribute(:data)) end def data=(value) write_attribute(:data, value.to_json) end end
  • 40. objspace.so > ObjectSpace.count_objects => {:TOTAL=>51359, :FREE=>16314, :T_OBJECT=>1356 ... > require 'objspace' > ObjectSpace.memsize_of(Class) => 1096 > ObjectSpace.reachable_objects_from(Class) => [#<InternalObject:0x007f87acf06e10 T_CLASS>, Class... > ObjectSpace.trace_object_allocations_start > str = "x" * 1024 * 1024 * 10 > ObjectSpace.allocation_generation(str) => 11
  • 42. RubyProf Memory Profiling require 'ruby-prof' RubyProf.measure_mode = RubyProf::MEMORY RubyProf.start str = 'x'*1024*1024*10 result = RubyProf.stop printer = RubyProf::FlatPrinter.new(result) printer.print(STDOUT) This requires patched Ruby, will work only for 1.8 and 1.9 https://github.com/ruby-prof/ruby-prof/issues/86
  • 43. Valgrind Memory Profiling > valgrind --tool=massif `rbenv which irb` ==9395== Massif, a heap profiler irb(main):001:0> x = "x"*1024*1024*10; nil => nil ==9395== > ms_print massif.out.9395 > massif-visualizer massif.out.9395 http://valgrind.org https://projects.kde.org/projects/extragear/sdk/massif-visualizer
  • 44.
  • 45. http://www.slideshare.net/adymo/adymo-railsconf-improveperformance Sign up for my upcoming book updates: ruby-performance-book.com Ask me: alex@alexdymo.com @alexander_dymo AirPair with me: airpair.me/adymo

Notas do Editor

  1. Ok, Let&amp;apos;s talk about performance Can I have a show of hands. Who here thinks Ruby is fast: C&amp;apos;mon, only a few people – I disagree, Ruby is fast, especially the latest version except for one thing – memory consumption and garbage collection make it slow. Oh, most people here think it&amp;apos;s fast – I do agree, ruby is fast until your program takes so much memory that it becomes slow.
  2. Why am I talking so much about memory? Here&amp;apos;s why.
  3. Why? Two reasons: Large memory overhead where every object takes at least 40 bytes in memory Plus Slow gc algorithm that got improved in 2.1 but not as much as we will later see That all equals not universal love an peace
  4. But high memory consumption and because of that enormous time that app spends doing GC That is why memory optimization is so important. It saves you that GC time That&amp;apos;s also why Ruby 2.1 is so important. It makes GC so much faster.
  5. Some examples from my own experience.
  6. Here&amp;apos;s another example. No memory optimization done, but Ruby upgraded from 1.9 to 2.1
  7. But here&amp;apos;s another thing. If you can upgrade – fine. If not - you can still get same and better performance by optimizing memory.
  8. How does tuning help? You can balance... By default this balance is to do more GC and reduce memory peaks. You can shift this balance. Change GC settings and see how often GC is called and what your memory usage is
  9. Let&amp;apos;s step back for a minute and look when GC is triggered
  10. There has been a sentiment inside Rails community that sql is somehow bad, that you should avoid it at all costs. People invent more and more things to stay out of sql. Just to mention AREL. Guys, I wholeheartedly disagree with this. Web frameworks come and go. Sql stays. We had sql for 40 years. It&amp;apos;s not going away.
  11. So, our time is out. If you&amp;apos;d like to learn more about ruby performance optimization, please sign up for my book mailing list updates. If you need help, just email me or airpair with me. And thank you for listening.