SlideShare a Scribd company logo
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

Fatc
FatcFatc
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
Kacper Gunia
 
Living with garbage
Living with garbageLiving with garbage
Living with garbage
lucenerevolution
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
Dr 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 CakePHP
Mariano Iglesias
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
Flavio Poletti
 
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 Firebase
Chetan 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 think
Wim Godden
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
Marcello Duarte
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
Flavio Poletti
 
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 Town
Ross Tuck
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty Burgers
Aaron 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 Techniques
Kris Wallsmith
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
David 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 Old
Ross 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 Rails
tdc-globalcode
 
Internacionalização da carreira
Internacionalização da carreiraInternacionalização da carreira
Internacionalização da carreira
tdc-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 hana
tdc-globalcode
 
Unit Tests e Xcode Server
Unit Tests e Xcode ServerUnit Tests e Xcode Server
Unit Tests e Xcode Server
tdc-globalcode
 
Empreendedorismo no Brasil
Empreendedorismo no BrasilEmpreendedorismo no Brasil
Empreendedorismo no Brasil
tdc-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 .NET
tdc-globalcode
 
Empreendedores brasileiros perfis_percepcoes_relatorio_completo
Empreendedores brasileiros perfis_percepcoes_relatorio_completoEmpreendedores brasileiros perfis_percepcoes_relatorio_completo
Empreendedores brasileiros perfis_percepcoes_relatorio_completo
Pedro Quintanilha
 
Gerenciando recursos computacionais com Apache Mesos
Gerenciando recursos computacionais com Apache MesosGerenciando recursos computacionais com Apache Mesos
Gerenciando recursos computacionais com Apache Mesos
tdc-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 code
Wim Godden
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
Engine 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 Know
Chris Oliver
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Service
vvatikiotis
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
Jens-Christian Fischer
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
David 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 2013
Joao Lucas Santana
 
Otimizando seu projeto Rails
Otimizando seu projeto RailsOtimizando seu projeto Rails
Otimizando seu projeto Rails
Tiago Albineli Motta
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
Kevin Swiber
 
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
ManageIQ
 
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
Wesley Beary
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan Wintermeyer
Elixir 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 code
Wim Godden
 
Scale 16x: Terraform all the Things
Scale 16x: Terraform all the ThingsScale 16x: Terraform all the Things
Scale 16x: Terraform all the Things
Nathan 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 Workshop
Wolfram 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 humanidade
tdc-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 Sucesso
tdc-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 GPA
tdc-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 OpenVino
tdc-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 devices
tdc-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 Publica
tdc-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 Easylocus
tdc-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 Golang
tdc-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 QA
tdc-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 tendencia
tdc-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 Service
tdc-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 .NET
tdc-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 8
tdc-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 Core
tdc-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

Multithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race conditionMultithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race condition
Mohammed Sikander
 
A Survey of Techniques for Maximizing LLM Performance.pptx
A Survey of Techniques for Maximizing LLM Performance.pptxA Survey of Techniques for Maximizing LLM Performance.pptx
A Survey of Techniques for Maximizing LLM Performance.pptx
thanhdowork
 
Synthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptxSynthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptx
Pavel ( NSTU)
 
Unit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdfUnit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdf
Thiyagu K
 
Operation Blue Star - Saka Neela Tara
Operation Blue Star   -  Saka Neela TaraOperation Blue Star   -  Saka Neela Tara
Operation Blue Star - Saka Neela Tara
Balvir Singh
 
The basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptxThe basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptx
heathfieldcps1
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
Peter Windle
 
Azure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHatAzure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHat
Scholarhat
 
Digital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion DesignsDigital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion Designs
chanes7
 
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Dr. Vinod Kumar Kanvaria
 
The Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptxThe Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptx
DhatriParmar
 
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
EugeneSaldivar
 
Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.
Ashokrao Mane college of Pharmacy Peth-Vadgaon
 
The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
Delapenabediema
 
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
MysoreMuleSoftMeetup
 
Digital Tools and AI for Teaching Learning and Research
Digital Tools and AI for Teaching Learning and ResearchDigital Tools and AI for Teaching Learning and Research
Digital Tools and AI for Teaching Learning and Research
Vikramjit Singh
 
Unit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdfUnit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdf
Thiyagu K
 
How libraries can support authors with open access requirements for UKRI fund...
How libraries can support authors with open access requirements for UKRI fund...How libraries can support authors with open access requirements for UKRI fund...
How libraries can support authors with open access requirements for UKRI fund...
Jisc
 
Thesis Statement for students diagnonsed withADHD.ppt
Thesis Statement for students diagnonsed withADHD.pptThesis Statement for students diagnonsed withADHD.ppt
Thesis Statement for students diagnonsed withADHD.ppt
EverAndrsGuerraGuerr
 
Embracing GenAI - A Strategic Imperative
Embracing GenAI - A Strategic ImperativeEmbracing GenAI - A Strategic Imperative
Embracing GenAI - A Strategic Imperative
Peter Windle
 

Recently uploaded (20)

Multithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race conditionMultithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race condition
 
A Survey of Techniques for Maximizing LLM Performance.pptx
A Survey of Techniques for Maximizing LLM Performance.pptxA Survey of Techniques for Maximizing LLM Performance.pptx
A Survey of Techniques for Maximizing LLM Performance.pptx
 
Synthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptxSynthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptx
 
Unit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdfUnit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdf
 
Operation Blue Star - Saka Neela Tara
Operation Blue Star   -  Saka Neela TaraOperation Blue Star   -  Saka Neela Tara
Operation Blue Star - Saka Neela Tara
 
The basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptxThe basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptx
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
 
Azure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHatAzure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHat
 
Digital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion DesignsDigital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion Designs
 
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
 
The Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptxThe Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptx
 
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
 
Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.
 
The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
 
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
 
Digital Tools and AI for Teaching Learning and Research
Digital Tools and AI for Teaching Learning and ResearchDigital Tools and AI for Teaching Learning and Research
Digital Tools and AI for Teaching Learning and Research
 
Unit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdfUnit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdf
 
How libraries can support authors with open access requirements for UKRI fund...
How libraries can support authors with open access requirements for UKRI fund...How libraries can support authors with open access requirements for UKRI fund...
How libraries can support authors with open access requirements for UKRI fund...
 
Thesis Statement for students diagnonsed withADHD.ppt
Thesis Statement for students diagnonsed withADHD.pptThesis Statement for students diagnonsed withADHD.ppt
Thesis Statement for students diagnonsed withADHD.ppt
 
Embracing GenAI - A Strategic Imperative
Embracing GenAI - A Strategic ImperativeEmbracing GenAI - A Strategic Imperative
Embracing GenAI - A Strategic Imperative
 

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