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

Alexander Dymo
Alexander DymoDirector of Engineering at Acunote
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
Alexander Dymo - RailsConf 2014 - Improve performance: Optimize Memory and Upgrade to Ruby 2.1
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
1 of 45

Recommended

Replacing ActiveRecord With DataMapper by
Replacing ActiveRecord With DataMapperReplacing ActiveRecord With DataMapper
Replacing ActiveRecord With DataMapperPeter Degen-Portnoy
2.9K views32 slides
Hadoop world g1_gc_forh_base_v4 by
Hadoop world g1_gc_forh_base_v4Hadoop world g1_gc_forh_base_v4
Hadoop world g1_gc_forh_base_v4YanpingWang
837 views11 slides
Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz... by
Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...
Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...Spark Summit
6K views24 slides
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia by
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital KediaTuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital KediaDatabricks
11.7K views32 slides
Cost-Based Optimizer in Apache Spark 2.2 by
Cost-Based Optimizer in Apache Spark 2.2 Cost-Based Optimizer in Apache Spark 2.2
Cost-Based Optimizer in Apache Spark 2.2 Databricks
5.5K views55 slides
Building a Distributed Data Streaming Architecture for Modern Hardware with S... by
Building a Distributed Data Streaming Architecture for Modern Hardware with S...Building a Distributed Data Streaming Architecture for Modern Hardware with S...
Building a Distributed Data Streaming Architecture for Modern Hardware with S...ScyllaDB
1.2K views13 slides

More Related Content

What's hot

Vertica mpp columnar dbms by
Vertica mpp columnar dbmsVertica mpp columnar dbms
Vertica mpp columnar dbmsZvika Gutkin
3.6K views27 slides
Vertica architecture by
Vertica architectureVertica architecture
Vertica architectureZvika Gutkin
2.7K views42 slides
Scio - A Scala API for Google Cloud Dataflow & Apache Beam by
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 BeamNeville Li
5.7K views47 slides
SparkR - Play Spark Using R (20160909 HadoopCon) by
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)wqchen
2.1K views47 slides
PostgreSQL on AWS: Tips & Tricks (and horror stories) by
PostgreSQL on AWS: Tips & Tricks (and horror stories)PostgreSQL on AWS: Tips & Tricks (and horror stories)
PostgreSQL on AWS: Tips & Tricks (and horror stories)Alexander Kukushkin
4.2K views50 slides
How to performance tune spark applications in large clusters by
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 clustersOmkar Joshi
94 views28 slides

What's hot(20)

Vertica mpp columnar dbms by Zvika Gutkin
Vertica mpp columnar dbmsVertica mpp columnar dbms
Vertica mpp columnar dbms
Zvika Gutkin3.6K views
Vertica architecture by Zvika Gutkin
Vertica architectureVertica architecture
Vertica architecture
Zvika Gutkin2.7K views
Scio - A Scala API for Google Cloud Dataflow & Apache Beam by Neville Li
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
Neville Li5.7K views
SparkR - Play Spark Using R (20160909 HadoopCon) by wqchen
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)
wqchen2.1K views
PostgreSQL on AWS: Tips & Tricks (and horror stories) by Alexander Kukushkin
PostgreSQL on AWS: Tips & Tricks (and horror stories)PostgreSQL on AWS: Tips & Tricks (and horror stories)
PostgreSQL on AWS: Tips & Tricks (and horror stories)
Alexander Kukushkin4.2K views
How to performance tune spark applications in large clusters by Omkar Joshi
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
Omkar Joshi94 views
Shipping Data from Postgres to Clickhouse, by Murat Kabilov, Adjust by Altinity Ltd
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
Altinity Ltd7.1K views
How Adobe Does 2 Million Records Per Second Using Apache Spark! by Databricks
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!
Databricks614 views
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a... by Altinity Ltd
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...
Altinity Ltd3.4K views
RDFox Poster by DBOnto
RDFox PosterRDFox Poster
RDFox Poster
DBOnto904 views
Upgrading To The New Map Reduce API by Tom Croucher
Upgrading To The New Map Reduce APIUpgrading To The New Map Reduce API
Upgrading To The New Map Reduce API
Tom Croucher25.6K views
HBaseCon2017 Quanta: Quora's hierarchical counting system on HBase by HBaseCon
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
HBaseCon608 views
Prediction as a service with ensemble model in SparkML and Python ScikitLearn by Josef A. Habdank
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
Josef A. Habdank1.8K views
S3, Cassandra or Outer Space? Dumping Time Series Data using Spark - Demi Ben... by Codemotion Tel Aviv
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 ... by Accumulo Summit
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 Summit590 views
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ... by 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 Summit675 views
Apache Sqoop: A Data Transfer Tool for Hadoop by Cloudera, Inc.
Apache Sqoop: A Data Transfer Tool for HadoopApache Sqoop: A Data Transfer Tool for Hadoop
Apache Sqoop: A Data Transfer Tool for Hadoop
Cloudera, Inc.19.9K views
Audience counting at Scale by b0ris_1
Audience counting at ScaleAudience counting at Scale
Audience counting at Scale
b0ris_11.7K views
Adventures in Observability: How in-house ClickHouse deployment enabled Inst... by Altinity Ltd
 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...
Altinity Ltd950 views

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

Enterprise application performance - Understanding & Learnings by
Enterprise application performance - Understanding & LearningsEnterprise application performance - Understanding & Learnings
Enterprise application performance - Understanding & LearningsDhaval Shah
318 views18 slides
Cold fusion is racecar fast by
Cold fusion is racecar fastCold fusion is racecar fast
Cold fusion is racecar fastColdFusionConference
819 views32 slides
Debugging Memory Problems in Rails by
Debugging Memory Problems in RailsDebugging Memory Problems in Rails
Debugging Memory Problems in RailsNasos Psarrakos
163 views14 slides
Handling 20 billion requests a month by
Handling 20 billion requests a monthHandling 20 billion requests a month
Handling 20 billion requests a monthDmitriy Dumanskiy
1.5K views88 slides
6 tips for improving ruby performance by
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performanceEngine Yard
6.6K views39 slides
Jvm Performance Tunning by
Jvm Performance TunningJvm Performance Tunning
Jvm Performance TunningTerry Cho
2.9K views71 slides

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

Enterprise application performance - Understanding & Learnings by Dhaval Shah
Enterprise application performance - Understanding & LearningsEnterprise application performance - Understanding & Learnings
Enterprise application performance - Understanding & Learnings
Dhaval Shah318 views
Debugging Memory Problems in Rails by Nasos Psarrakos
Debugging Memory Problems in RailsDebugging Memory Problems in Rails
Debugging Memory Problems in Rails
Nasos Psarrakos163 views
6 tips for improving ruby performance by Engine Yard
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
Engine Yard6.6K views
Jvm Performance Tunning by Terry Cho
Jvm Performance TunningJvm Performance Tunning
Jvm Performance Tunning
Terry Cho2.9K views
Jvm Performance Tunning by guest1f2740
Jvm Performance TunningJvm Performance Tunning
Jvm Performance Tunning
guest1f2740941 views
DevoxxUK: Optimizating Application Performance on Kubernetes by Dinakar Guniguntala
DevoxxUK: Optimizating Application Performance on KubernetesDevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on Kubernetes
Tweaking performance on high-load projects by Dmitriy Dumanskiy
Tweaking performance on high-load projectsTweaking performance on high-load projects
Tweaking performance on high-load projects
Dmitriy Dumanskiy2.5K views
(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features by Amazon Web Services
(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features
(DAT402) Amazon RDS PostgreSQL:Lessons Learned & New Features
Amazon Web Services30.9K views
Java 어플리케이션 성능튜닝 Part1 by 상욱 송
Java 어플리케이션 성능튜닝 Part1Java 어플리케이션 성능튜닝 Part1
Java 어플리케이션 성능튜닝 Part1
상욱 송948 views
Hadoop Summit Amsterdam 2014: Capacity Planning In Multi-tenant Hadoop Deploy... by Sumeet Singh
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...
Sumeet Singh1.5K views
State of Java Elasticity. Tuning Java Efficiency - GIDS.JAVA LIVE 2020 by Jelastic Multi-Cloud PaaS
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 by Tatsuhiro Chiba
JVM and OS Tuning for accelerating Spark applicationJVM and OS Tuning for accelerating Spark application
JVM and OS Tuning for accelerating Spark application
Tatsuhiro Chiba6.4K views
Tweaking perfomance on high-load projects_Думанский Дмитрий by GeeksLab Odessa
Tweaking perfomance on high-load projects_Думанский ДмитрийTweaking perfomance on high-load projects_Думанский Дмитрий
Tweaking perfomance on high-load projects_Думанский Дмитрий
GeeksLab Odessa10.6K views
Toronto meetup 20190917 by Bill Liu
Toronto meetup 20190917Toronto meetup 20190917
Toronto meetup 20190917
Bill Liu393 views
Big data should be simple by Dori Waldman
Big data should be simpleBig data should be simple
Big data should be simple
Dori Waldman578 views
millions-gc-jax-2022.pptx by Tier1 app
millions-gc-jax-2022.pptxmillions-gc-jax-2022.pptx
millions-gc-jax-2022.pptx
Tier1 app141 views

Recently uploaded

Mobile App Development Company by
Mobile App Development CompanyMobile App Development Company
Mobile App Development CompanyRichestsoft
5 views6 slides
Streamlining Your Business Operations with Enterprise Application Integration... by
Streamlining Your Business Operations with Enterprise Application Integration...Streamlining Your Business Operations with Enterprise Application Integration...
Streamlining Your Business Operations with Enterprise Application Integration...Flexsin
5 views12 slides
How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile... by
How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile...How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile...
How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile...Stefan Wolpers
42 views38 slides
Agile 101 by
Agile 101Agile 101
Agile 101John Valentino
12 views20 slides
How Workforce Management Software Empowers SMEs | TraQSuite by
How Workforce Management Software Empowers SMEs | TraQSuiteHow Workforce Management Software Empowers SMEs | TraQSuite
How Workforce Management Software Empowers SMEs | TraQSuiteTraQSuite
6 views3 slides
Supercharging your Python Development Environment with VS Code and Dev Contai... by
Supercharging your Python Development Environment with VS Code and Dev Contai...Supercharging your Python Development Environment with VS Code and Dev Contai...
Supercharging your Python Development Environment with VS Code and Dev Contai...Dawn Wages
5 views51 slides

Recently uploaded(20)

Mobile App Development Company by Richestsoft
Mobile App Development CompanyMobile App Development Company
Mobile App Development Company
Richestsoft 5 views
Streamlining Your Business Operations with Enterprise Application Integration... by Flexsin
Streamlining Your Business Operations with Enterprise Application Integration...Streamlining Your Business Operations with Enterprise Application Integration...
Streamlining Your Business Operations with Enterprise Application Integration...
Flexsin 5 views
How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile... by Stefan Wolpers
How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile...How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile...
How To Make Your Plans Suck Less — Maarten Dalmijn at the 57th Hands-on Agile...
Stefan Wolpers42 views
How Workforce Management Software Empowers SMEs | TraQSuite by TraQSuite
How Workforce Management Software Empowers SMEs | TraQSuiteHow Workforce Management Software Empowers SMEs | TraQSuite
How Workforce Management Software Empowers SMEs | TraQSuite
TraQSuite6 views
Supercharging your Python Development Environment with VS Code and Dev Contai... by Dawn Wages
Supercharging your Python Development Environment with VS Code and Dev Contai...Supercharging your Python Development Environment with VS Code and Dev Contai...
Supercharging your Python Development Environment with VS Code and Dev Contai...
Dawn Wages5 views
Bootstrapping vs Venture Capital.pptx by Zeljko Svedic
Bootstrapping vs Venture Capital.pptxBootstrapping vs Venture Capital.pptx
Bootstrapping vs Venture Capital.pptx
Zeljko Svedic15 views
FOSSLight Community Day 2023-11-30 by Shane Coughlan
FOSSLight Community Day 2023-11-30FOSSLight Community Day 2023-11-30
FOSSLight Community Day 2023-11-30
Shane Coughlan7 views
Understanding HTML terminology by artembondar5
Understanding HTML terminologyUnderstanding HTML terminology
Understanding HTML terminology
artembondar57 views
Dapr Unleashed: Accelerating Microservice Development by Miroslav Janeski
Dapr Unleashed: Accelerating Microservice DevelopmentDapr Unleashed: Accelerating Microservice Development
Dapr Unleashed: Accelerating Microservice Development
Miroslav Janeski15 views
Ports-and-Adapters Architecture for Embedded HMI by Burkhard Stubert
Ports-and-Adapters Architecture for Embedded HMIPorts-and-Adapters Architecture for Embedded HMI
Ports-and-Adapters Architecture for Embedded HMI
Burkhard Stubert33 views
Top-5-production-devconMunich-2023-v2.pptx by Tier1 app
Top-5-production-devconMunich-2023-v2.pptxTop-5-production-devconMunich-2023-v2.pptx
Top-5-production-devconMunich-2023-v2.pptx
Tier1 app8 views
Introduction to Git Source Control by John Valentino
Introduction to Git Source ControlIntroduction to Git Source Control
Introduction to Git Source Control
John Valentino7 views
Advanced API Mocking Techniques Using Wiremock by Dimpy Adhikary
Advanced API Mocking Techniques Using WiremockAdvanced API Mocking Techniques Using Wiremock
Advanced API Mocking Techniques Using Wiremock
Dimpy Adhikary5 views

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
  • 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

Editor's Notes

  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.