SlideShare a Scribd company logo
1 of 81
Download to read offline
Performance
vamos dormir mais!
Marcelo Cajueiro
• 5 anos trabalhando com Ruby on Rails
• Engenheiro e líder no Enjoei =P
• Não toco nenhum instrumento
• Nick no chat da uol: tatuado_25_na_cam !
• http://cajueiro.me
Disclaimer
( °□° )
Barba + Relógio = Maior confiança 1
1
Fonte: broscience (papo de homem - http://goo.gl/ZzyKup)
Tarot da Startup
Réplica no banco de dados
gem 'octopus'
class Badge < ActiveRecord::Base
replicated_model
end
Badge.where(user_id: 1) # usa réplica
@user = User.using(:shard1).find_by_name("Joao")
PS.: use com sabedoria.
Rake tasks & réplica
$ DATABASE_URL=postgresql://replica_url rake reports:all
para emails
Sidekiq::Extensions::DelayedMailer.
sidekiq_options queue: :read_only_default
InviteMailer.delay.new_invite
para workers
class ReportWorker
include Sidekiq::Worker
sidekiq_options queue: :read_only_default
end
$ DATABASE_URL="postgresql://replica_url"
sidekiq -c 10 -q read_only_default,2
Queries N+1
http://goo.gl/2j191w 2
2
http://blog.arkency.com/2013/12/rails4-preloading/
Usuário
seguindo
outros usuários
class User
has_many :user_follows
has_many :followers,
through: :user_follows,
class_name: 'User',
foreign_key: 'follower_id'
has_many :following,
through: :user_follows,
class_name: 'User',
foreign_key: 'user_id'
end
class UserFollow
belongs_to :user
belongs_to :follower, class_name: "User"
end
Uma query por usuário
User.limit(10).each do |user|
# Eu estou seguindo esse usuário?
if current_user.following.where(id: user.id).exists?
# imprime o botão "deixar de seguir"
else
# imprime o botão "seguir"
end
end
A solução mais simples geralmente não é a mais performática.
Salvando os ids de quem eu sigo
# E se eu estiver seguindo 90mil usuários?
following_ids = current_user.following_ids
User.limit(10).each do |user|
if following_ids.include?(user.id)
# imprime o botão "deixar de seguir"
else
# imprime o botão "seguir"
end
end
Pegando os ids que estou listando
e vendo quem eu sigo
users = User.limit(10)
user_ids = users.map(&:id) # pluck? no :)
following_ids = current_user.
following.where(id: user_ids).pluck(:id)
users.each do |user|
if following_ids.include?(user.id)
# imprime o botão "deixar de seguir"
else
# imprime o botão "seguir"
end
end
Fine tune
Com INNER JOIN
following_ids = current_user.
following.where(id: user_ids).pluck(:id)
SELECT "users"."id"
FROM "users"
INNER JOIN "user_follows"
ON "users"."id" = "user_follows"."user_id"
WHERE "user_follows"."follower_id" = 1
Sem INNER JOIN
following_ids = UserFollow.
where(follower_id: current_user.id).
pluck(:user_id)
SELECT "user_follows"."user_id"
FROM "user_follows"
WHERE "user_follows"."follower_id" = 1
Nem sempre o que o Rails tem pronto é o melhor.
gem 'bullet'
Chata! Alert, honeybadger, airbrake, slack, etc.
gem 'rack-mini-profiler'
gem 'newrelic_rpm'
localhost:3000/newrelic
Dashboard
• data da primeira compra
• data da última compra
• número de compras
• total gasto
• categorias compradas
• marcas compradas
Informações triviais sozinhas
class User
def first_purchase_at
orders.minimum(:sold_at)
end
def last_purchase_at
orders.maximum(:sold_at)
end
def purchases_count
orders.count
end
end
Informações triviais sozinhas
class User
def purchases_total_price
orders.sum(:price)
end
def purchased_brands
purchased_products.pluck(:brand).uniq
end
def purchased_brands
purchased_products.pluck(:category).uniq
end
end
6 consultas
user.orders.minimum(:sold_at)
user.orders.maximum(:sold_at)
user.orders.count
user.orders.sum(:price)
user.purchased_products.pluck(:brand).uniq
user.purchased_products.pluck(:category).uniq
SQL + Ruby aggregation
purchases = user.orders.
order(sold_at: :desc).
joins(:product).select(
"orders.sold_at",
"orders.price",
"products.brand",
"products.category"
).to_a
SQL + Ruby aggregation
purchases.sum(&:price)
purchases.map(&:brand).uniq
purchases.map(&:category).uniq
purchases.first.sold_at
purchases.last.sold_at
purchases.count
SQL aggregation
purchases = user.orders.select(
"max(orders.sold_at) AS last_purchased_at",
"min(orders.sold_at) AS first_purchased_at",
"sum(orders.price) AS total_price",
"count(orders.id) AS total"
).to_a.first
SQL aggregation
# Query 1
purchases.total_price
purchases.last_purchased_at
purchases.first_purchased_at
purchases.total
# Query 2
user.purchased_products.pluck('DISTINCT(brand)')
# Query 3
user.purchased_products.pluck('DISTINCT(category_id)')
Opções
1 - todas as informacões em queries
separadas
2 - uma query com todos os dados
separados e calculando com ruby
3 - uma query com os campos
calculados e outras duas para o
restante
Benchmark 3
3
https://github.com/evanphx/benchmark-ips
Calculating -------------------------------------
queries separadas 3.000 i/100ms
cálculo SQL + queries 8.000 i/100ms
SQL + cálculo ruby 1.000 i/100ms
-------------------------------------------------
queries separadas 46.789 (± 8.5%) i/s - 234.000
cálculo SQL + queries 81.732 (± 9.8%) i/s - 408.000
SQL + cálculo ruby 2.314 (± 0.0%) i/s - 12.000
Comparison:
cálculo SQL + queries: 81.7 i/s
queries separadas: 46.8 i/s - 1.75x slower
SQL + cálculo ruby: 2.3 i/s - 35.32x slower
Mais um exemplo
photos.order('CASE WHEN selected = true
THEN 0
ELSE COALESCE(position, 0) + 1 END')
Ou
photos.sort_by do |photo|
if photo.selected?
0
else
photo.position.to_i + 1
end
end
Calculating -------------------------------------
SQL 1.000 i/100ms
Array 1.000 i/100ms
-------------------------------------------------
SQL 1.054k (± 8.1%) i/s - 5.074k
Array 95.344 (± 9.4%) i/s - 468.000
Comparison:
SQL: 1053.8 i/s
Array: 95.3 i/s - 11.05x slower
Mais sobre ordenação
Ordenação na query + limit
EXPLAIN SELECT * FROM messages
WHERE user_id = 1
ORDER BY id DESC LIMIT 10
Limit (cost=539.60..539.63 rows=10 width=115)
-> Sort (cost=539.60..539.94 rows=136 width=115)
Sort Key: id
-> Bitmap Heap Scan on messages
(cost=5.49..536.67 rows=136 width=115)
Recheck Cond: (user_id = 1)
-> Bitmap Index Scan on index_messages_on_user_id
(cost=0.00..5.45 rows=136 width=0)
Index Cond: (user_id = 1)
Usando índice com ordenação
CREATE INDEX index_messages_ordered_on_user_id
ON messages (user_id, id DESC)
Limit (cost=0.43..40.78 rows=10 width=115)
-> Index Scan using index_messages_ordered_on_user_id on messages
(cost=0.43..549.14 rows=136 width=115)
Index Cond: (user_id = 1)
Cache
• Fragment
• Russian doll
• Rack
• HTTP
Speed Up Your Rails App by 66% - The Complete Guide to
Rails Caching 4
4
From Nate Berkopec
gem 'identity_cache'
class Product < ActiveRecord::Base
include IdentityCache
has_many :photos
belongs_to :category
cache_has_many :photos
cache_belongs_to :category
end
product = Product.fetch(1)
product.fetch_photos
product.fetch_category
class Photo < ActiveRecord::Base
include IdentityCache
cache_index :imageable_type, :imageable_id
end
class Product < ActiveRecord::Base
def cached_images
Photo.
fetch_by_imageable_type_and_imageable_id(
'Product', id
)
end
end
Counter cache
• Implementação do Rails
class Order < ActiveRecord::Base
belongs_to :customer, counter_cache: true
end
class Customer < ActiveRecord::Base
has_many :orders
end
@customer.orders.size
@customer.orders.count
Counter cache
gem 'counter_culture'
class Product < ActiveRecord::Base
belongs_to :sub_category
counter_culture :category,
:column_name => Proc.new { |model|
model.special? ? 'special_count' : nil
}
end
@category.special_count
Paginação
• usar o counter cache para calcular a numeração
• remover a numeração das páginas
current_user.
followers.
paginate(per_page: 10,
page: params[:page],
total_entries: current_user.followers_count)
Remover locks pessismistas desnecessários
Comment.lock.find(1).destroy
comment = Comment.find(1)
comment.with_lock do
comment.destroy!
end
Admin no servidor do usuário final
• Admin é sempre mais lento
• Tem Relatórios
• Cheio de ações demoradas
Boa solução
• Proxy reverso
Lazy load na interface
• Por que carregar os comentários na ação principal?
• Por que carregar os produtos relacionados na ação
principal?
• ...
Migration sem lock na tabela
class AddIndexToMessages < ActiveRecord::Migration
disable_ddl_transaction!
def change
add_index :messages, :user_id, algorithm: :concurrently
end
end
jobs.lever.co/enjoei
Muito obrigado!
Sugestões?
Perguntas?
Referência das imagens
• https://en.wikipedia.org/wiki/Rider-Waitetarotdeck
• http://www.maxi-geek.com/2015/05/the-flash-vs-superman-
who-will-bleed.html
• https://sobeso.com/beating-creative-block
• http://www.motherhoodcenter.com/sleep-coach/
• http://9to5mac.com/2015/03/06/sources-offer-hands-on-
apple-watch-details-battery-life-unannounced-features-and-
more/
E mais referência das imagens
• http://www.jackiealpers.com/mysteries-rituals/the-world-
photograph-of-a-man-holding-a-tarot-card-by-jackie-
alpers-728153.html
• http://thezt2roundtable.com/search/5/?
c=3&mid=3525512&month=4&year=2015
• http://www.fanpop.com/clubs/jaime-lannister/images/
37085417/title/jaime-tyrion-lannister-photo/7

More Related Content

What's hot

Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteDr Nic Williams
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPMariano Iglesias
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Kris Wallsmith
 
Launching Beeline with Firebase
Launching Beeline with FirebaseLaunching Beeline with Firebase
Launching Beeline with FirebaseChetan Padia
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128PrinceGuru MS
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersAaron Patterson
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionAdam Trachtenberg
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in OptimizationDavid Golden
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 

What's hot (20)

Fatc
FatcFatc
Fatc
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Living with garbage
Living with garbageLiving with garbage
Living with garbage
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
Launching Beeline with Firebase
Launching Beeline with FirebaseLaunching Beeline with Firebase
Launching Beeline with Firebase
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty Burgers
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 

Viewers also liked

Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos RailsPolo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Railstdc-globalcode
 
Internacionalização da carreira
Internacionalização da carreiraInternacionalização da carreira
Internacionalização da carreiratdc-globalcode
 
sap startup focus acelerando startups brasileiras com sap hana
sap startup focus acelerando startups brasileiras  com sap  hanasap startup focus acelerando startups brasileiras  com sap  hana
sap startup focus acelerando startups brasileiras com sap hanatdc-globalcode
 
Unit Tests e Xcode Server
Unit Tests e Xcode ServerUnit Tests e Xcode Server
Unit Tests e Xcode Servertdc-globalcode
 
Empreendedorismo no Brasil
Empreendedorismo no BrasilEmpreendedorismo no Brasil
Empreendedorismo no Brasiltdc-globalcode
 
Dividindo para conquistar: microservicos com o jeitinho .NET
Dividindo para conquistar: microservicos com o jeitinho .NETDividindo para conquistar: microservicos com o jeitinho .NET
Dividindo para conquistar: microservicos com o jeitinho .NETtdc-globalcode
 
Empreendedores brasileiros perfis_percepcoes_relatorio_completo
Empreendedores brasileiros perfis_percepcoes_relatorio_completoEmpreendedores brasileiros perfis_percepcoes_relatorio_completo
Empreendedores brasileiros perfis_percepcoes_relatorio_completoPedro Quintanilha
 
Gerenciando recursos computacionais com Apache Mesos
Gerenciando recursos computacionais com Apache MesosGerenciando recursos computacionais com Apache Mesos
Gerenciando recursos computacionais com Apache Mesostdc-globalcode
 

Viewers also liked (8)

Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos RailsPolo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
 
Internacionalização da carreira
Internacionalização da carreiraInternacionalização da carreira
Internacionalização da carreira
 
sap startup focus acelerando startups brasileiras com sap hana
sap startup focus acelerando startups brasileiras  com sap  hanasap startup focus acelerando startups brasileiras  com sap  hana
sap startup focus acelerando startups brasileiras com sap hana
 
Unit Tests e Xcode Server
Unit Tests e Xcode ServerUnit Tests e Xcode Server
Unit Tests e Xcode Server
 
Empreendedorismo no Brasil
Empreendedorismo no BrasilEmpreendedorismo no Brasil
Empreendedorismo no Brasil
 
Dividindo para conquistar: microservicos com o jeitinho .NET
Dividindo para conquistar: microservicos com o jeitinho .NETDividindo para conquistar: microservicos com o jeitinho .NET
Dividindo para conquistar: microservicos com o jeitinho .NET
 
Empreendedores brasileiros perfis_percepcoes_relatorio_completo
Empreendedores brasileiros perfis_percepcoes_relatorio_completoEmpreendedores brasileiros perfis_percepcoes_relatorio_completo
Empreendedores brasileiros perfis_percepcoes_relatorio_completo
 
Gerenciando recursos computacionais com Apache Mesos
Gerenciando recursos computacionais com Apache MesosGerenciando recursos computacionais com Apache Mesos
Gerenciando recursos computacionais com Apache Mesos
 

Similar to performance vamos dormir mais?

Intro to-rails-webperf
Intro to-rails-webperfIntro to-rails-webperf
Intro to-rails-webperfNew Relic
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeWim Godden
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performanceEngine Yard
 
Rails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowRails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowChris Oliver
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Servicevvatikiotis
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best PracticesDavid Keener
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Joao Lucas Santana
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonManageIQ
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the CloudWesley Beary
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerElixir Club
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
Scale 16x: Terraform all the Things
Scale 16x: Terraform all the ThingsScale 16x: Terraform all the Things
Scale 16x: Terraform all the ThingsNathan Handler
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD WorkshopWolfram Arnold
 

Similar to performance vamos dormir mais? (20)

Intro to-rails-webperf
Intro to-rails-webperfIntro to-rails-webperf
Intro to-rails-webperf
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the code
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
 
Rails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowRails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not Know
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Service
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
 
Rails Performance
Rails PerformanceRails Performance
Rails Performance
 
Otimizando seu projeto Rails
Otimizando seu projeto RailsOtimizando seu projeto Rails
Otimizando seu projeto Rails
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
 
ql.io at NodePDX
ql.io at NodePDXql.io at NodePDX
ql.io at NodePDX
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan Wintermeyer
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
Scale 16x: Terraform all the Things
Scale 16x: Terraform all the ThingsScale 16x: Terraform all the Things
Scale 16x: Terraform all the Things
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 

More from tdc-globalcode

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadetdc-globalcode
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...tdc-globalcode
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucessotdc-globalcode
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPAtdc-globalcode
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinotdc-globalcode
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...tdc-globalcode
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicestdc-globalcode
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publicatdc-globalcode
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#tdc-globalcode
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocustdc-globalcode
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?tdc-globalcode
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golangtdc-globalcode
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QAtdc-globalcode
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciatdc-globalcode
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Servicetdc-globalcode
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETtdc-globalcode
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8tdc-globalcode
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...tdc-globalcode
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#tdc-globalcode
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Coretdc-globalcode
 

More from tdc-globalcode (20)

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devices
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocus
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golang
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
 

Recently uploaded

Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...EduSkills OECD
 
JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...
JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...
JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...anjaliyadav012327
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeThiyagu K
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajanpragatimahajan3
 
Separation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and ActinidesSeparation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and ActinidesFatimaKhan178732
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...fonyou31
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfciinovamais
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Sapana Sha
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxSayali Powar
 
The byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptxThe byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptxShobhayan Kirtania
 
Disha NEET Physics Guide for classes 11 and 12.pdf
Disha NEET Physics Guide for classes 11 and 12.pdfDisha NEET Physics Guide for classes 11 and 12.pdf
Disha NEET Physics Guide for classes 11 and 12.pdfchloefrazer622
 
Sanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfSanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfsanyamsingh5019
 
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdfBASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdfSoniaTolstoy
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introductionMaksud Ahmed
 
Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfJayanti Pande
 
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxSOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxiammrhaywood
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Krashi Coaching
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Celine George
 

Recently uploaded (20)

Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
 
JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...
JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...
JAPAN: ORGANISATION OF PMDA, PHARMACEUTICAL LAWS & REGULATIONS, TYPES OF REGI...
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and Mode
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajan
 
Separation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and ActinidesSeparation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and Actinides
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
 
The byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptxThe byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptx
 
Disha NEET Physics Guide for classes 11 and 12.pdf
Disha NEET Physics Guide for classes 11 and 12.pdfDisha NEET Physics Guide for classes 11 and 12.pdf
Disha NEET Physics Guide for classes 11 and 12.pdf
 
Sanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfSanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdf
 
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdfBASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
 
Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdf
 
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxSOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17
 

performance vamos dormir mais?

  • 2. Marcelo Cajueiro • 5 anos trabalhando com Ruby on Rails • Engenheiro e líder no Enjoei =P • Não toco nenhum instrumento • Nick no chat da uol: tatuado_25_na_cam ! • http://cajueiro.me
  • 5.
  • 6. Barba + Relógio = Maior confiança 1 1 Fonte: broscience (papo de homem - http://goo.gl/ZzyKup)
  • 7.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27. Réplica no banco de dados
  • 28. gem 'octopus' class Badge < ActiveRecord::Base replicated_model end Badge.where(user_id: 1) # usa réplica @user = User.using(:shard1).find_by_name("Joao") PS.: use com sabedoria.
  • 29. Rake tasks & réplica $ DATABASE_URL=postgresql://replica_url rake reports:all
  • 30.
  • 31. para emails Sidekiq::Extensions::DelayedMailer. sidekiq_options queue: :read_only_default InviteMailer.delay.new_invite
  • 32. para workers class ReportWorker include Sidekiq::Worker sidekiq_options queue: :read_only_default end
  • 36. class User has_many :user_follows has_many :followers, through: :user_follows, class_name: 'User', foreign_key: 'follower_id' has_many :following, through: :user_follows, class_name: 'User', foreign_key: 'user_id' end
  • 37. class UserFollow belongs_to :user belongs_to :follower, class_name: "User" end
  • 38.
  • 39. Uma query por usuário User.limit(10).each do |user| # Eu estou seguindo esse usuário? if current_user.following.where(id: user.id).exists? # imprime o botão "deixar de seguir" else # imprime o botão "seguir" end end A solução mais simples geralmente não é a mais performática.
  • 40. Salvando os ids de quem eu sigo # E se eu estiver seguindo 90mil usuários? following_ids = current_user.following_ids User.limit(10).each do |user| if following_ids.include?(user.id) # imprime o botão "deixar de seguir" else # imprime o botão "seguir" end end
  • 41. Pegando os ids que estou listando e vendo quem eu sigo
  • 42. users = User.limit(10) user_ids = users.map(&:id) # pluck? no :) following_ids = current_user. following.where(id: user_ids).pluck(:id) users.each do |user| if following_ids.include?(user.id) # imprime o botão "deixar de seguir" else # imprime o botão "seguir" end end
  • 44. Com INNER JOIN following_ids = current_user. following.where(id: user_ids).pluck(:id) SELECT "users"."id" FROM "users" INNER JOIN "user_follows" ON "users"."id" = "user_follows"."user_id" WHERE "user_follows"."follower_id" = 1
  • 45. Sem INNER JOIN following_ids = UserFollow. where(follower_id: current_user.id). pluck(:user_id) SELECT "user_follows"."user_id" FROM "user_follows" WHERE "user_follows"."follower_id" = 1 Nem sempre o que o Rails tem pronto é o melhor.
  • 46. gem 'bullet' Chata! Alert, honeybadger, airbrake, slack, etc.
  • 49.
  • 50. Dashboard • data da primeira compra • data da última compra • número de compras • total gasto • categorias compradas • marcas compradas
  • 51. Informações triviais sozinhas class User def first_purchase_at orders.minimum(:sold_at) end def last_purchase_at orders.maximum(:sold_at) end def purchases_count orders.count end end
  • 52. Informações triviais sozinhas class User def purchases_total_price orders.sum(:price) end def purchased_brands purchased_products.pluck(:brand).uniq end def purchased_brands purchased_products.pluck(:category).uniq end end
  • 54. SQL + Ruby aggregation purchases = user.orders. order(sold_at: :desc). joins(:product).select( "orders.sold_at", "orders.price", "products.brand", "products.category" ).to_a
  • 55. SQL + Ruby aggregation purchases.sum(&:price) purchases.map(&:brand).uniq purchases.map(&:category).uniq purchases.first.sold_at purchases.last.sold_at purchases.count
  • 56. SQL aggregation purchases = user.orders.select( "max(orders.sold_at) AS last_purchased_at", "min(orders.sold_at) AS first_purchased_at", "sum(orders.price) AS total_price", "count(orders.id) AS total" ).to_a.first
  • 57. SQL aggregation # Query 1 purchases.total_price purchases.last_purchased_at purchases.first_purchased_at purchases.total # Query 2 user.purchased_products.pluck('DISTINCT(brand)') # Query 3 user.purchased_products.pluck('DISTINCT(category_id)')
  • 58. Opções 1 - todas as informacões em queries separadas 2 - uma query com todos os dados separados e calculando com ruby 3 - uma query com os campos calculados e outras duas para o restante
  • 60. Calculating ------------------------------------- queries separadas 3.000 i/100ms cálculo SQL + queries 8.000 i/100ms SQL + cálculo ruby 1.000 i/100ms ------------------------------------------------- queries separadas 46.789 (± 8.5%) i/s - 234.000 cálculo SQL + queries 81.732 (± 9.8%) i/s - 408.000 SQL + cálculo ruby 2.314 (± 0.0%) i/s - 12.000 Comparison: cálculo SQL + queries: 81.7 i/s queries separadas: 46.8 i/s - 1.75x slower SQL + cálculo ruby: 2.3 i/s - 35.32x slower
  • 61. Mais um exemplo photos.order('CASE WHEN selected = true THEN 0 ELSE COALESCE(position, 0) + 1 END') Ou photos.sort_by do |photo| if photo.selected? 0 else photo.position.to_i + 1 end end
  • 62. Calculating ------------------------------------- SQL 1.000 i/100ms Array 1.000 i/100ms ------------------------------------------------- SQL 1.054k (± 8.1%) i/s - 5.074k Array 95.344 (± 9.4%) i/s - 468.000 Comparison: SQL: 1053.8 i/s Array: 95.3 i/s - 11.05x slower
  • 64. Ordenação na query + limit EXPLAIN SELECT * FROM messages WHERE user_id = 1 ORDER BY id DESC LIMIT 10 Limit (cost=539.60..539.63 rows=10 width=115) -> Sort (cost=539.60..539.94 rows=136 width=115) Sort Key: id -> Bitmap Heap Scan on messages (cost=5.49..536.67 rows=136 width=115) Recheck Cond: (user_id = 1) -> Bitmap Index Scan on index_messages_on_user_id (cost=0.00..5.45 rows=136 width=0) Index Cond: (user_id = 1)
  • 65. Usando índice com ordenação CREATE INDEX index_messages_ordered_on_user_id ON messages (user_id, id DESC) Limit (cost=0.43..40.78 rows=10 width=115) -> Index Scan using index_messages_ordered_on_user_id on messages (cost=0.43..549.14 rows=136 width=115) Index Cond: (user_id = 1)
  • 66.
  • 67. Cache • Fragment • Russian doll • Rack • HTTP Speed Up Your Rails App by 66% - The Complete Guide to Rails Caching 4 4 From Nate Berkopec
  • 68. gem 'identity_cache' class Product < ActiveRecord::Base include IdentityCache has_many :photos belongs_to :category cache_has_many :photos cache_belongs_to :category end product = Product.fetch(1) product.fetch_photos product.fetch_category
  • 69. class Photo < ActiveRecord::Base include IdentityCache cache_index :imageable_type, :imageable_id end class Product < ActiveRecord::Base def cached_images Photo. fetch_by_imageable_type_and_imageable_id( 'Product', id ) end end
  • 70. Counter cache • Implementação do Rails class Order < ActiveRecord::Base belongs_to :customer, counter_cache: true end class Customer < ActiveRecord::Base has_many :orders end @customer.orders.size @customer.orders.count
  • 71. Counter cache gem 'counter_culture' class Product < ActiveRecord::Base belongs_to :sub_category counter_culture :category, :column_name => Proc.new { |model| model.special? ? 'special_count' : nil } end @category.special_count
  • 72. Paginação • usar o counter cache para calcular a numeração • remover a numeração das páginas current_user. followers. paginate(per_page: 10, page: params[:page], total_entries: current_user.followers_count)
  • 73. Remover locks pessismistas desnecessários Comment.lock.find(1).destroy comment = Comment.find(1) comment.with_lock do comment.destroy! end
  • 74. Admin no servidor do usuário final • Admin é sempre mais lento • Tem Relatórios • Cheio de ações demoradas Boa solução • Proxy reverso
  • 75. Lazy load na interface • Por que carregar os comentários na ação principal? • Por que carregar os produtos relacionados na ação principal? • ...
  • 76. Migration sem lock na tabela class AddIndexToMessages < ActiveRecord::Migration disable_ddl_transaction! def change add_index :messages, :user_id, algorithm: :concurrently end end
  • 77.
  • 80. Referência das imagens • https://en.wikipedia.org/wiki/Rider-Waitetarotdeck • http://www.maxi-geek.com/2015/05/the-flash-vs-superman- who-will-bleed.html • https://sobeso.com/beating-creative-block • http://www.motherhoodcenter.com/sleep-coach/ • http://9to5mac.com/2015/03/06/sources-offer-hands-on- apple-watch-details-battery-life-unannounced-features-and- more/
  • 81. E mais referência das imagens • http://www.jackiealpers.com/mysteries-rituals/the-world- photograph-of-a-man-holding-a-tarot-card-by-jackie- alpers-728153.html • http://thezt2roundtable.com/search/5/? c=3&mid=3525512&month=4&year=2015 • http://www.fanpop.com/clubs/jaime-lannister/images/ 37085417/title/jaime-tyrion-lannister-photo/7