Ruby Academy · Lektion

Vanliga flaskhalsar

Snabba upp Ruby-kod.

Lektion 4 av 413 steg

Vanliga flaskhalsar är en gratis lektion i Ruby Academy på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Ruby Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Ruby Academy innehåller totalt 4 lektioner.

Känna igen flaskhalsar

De flesta Ruby-försämringar i prestanda beror på några återkommande mönster. När du känner igen dem kan du snabbt åtgärda koden.

  • Fel datastruktur för uppgiften
  • Arbete som upprepas trots att det skulle kunna cachas
  • N+1-frågor och nästlade loopar

Den här lektionen tar upp de vanligaste problemen.

puts 'Speeding up Ruby starts with knowing the usual suspects'

<code>Array#include?</code> kontra <code>Set</code>

Att kontrollera medlemskap med Array#include? är O(n). En Set (eller hash-tabell) ger uppslagningar på O(1).

  • Vid upprepade medlemskapskontroller skapar du en Set en gång
  • Det ger en enorm hastighetsökning för stora samlingar
require 'set'

allowed = Set.new(['a', 'b', 'c'])
puts allowed.include?('b')
puts allowed.include?('z')

Nästlade loopar (O(n i kvadrat))

Att jämföra varje elementpar är kvadratiskt och växer explosionsartat med storleken.

  • Ersätt inre loopar med en hash-uppslagning
  • Förvandlar O(n i kvadrat) till O(n)
a = [1, 2, 3, 4]
b = [3, 4, 5]
set_b = b.to_set rescue require('set') || b.to_set
common = a.select { |x| set_b.include?(x) }
puts common.inspect

N+1-mönstret

Att hämta relaterade data inuti en loop leder till N+1-operationer.

  • En fråga för listan och sedan en per objekt
  • Samla i stället uppslagningarna i en enda grupperad hämtning
# Bad: lookup inside loop
orders = [1, 2, 3]
prices = { 1 => 10, 2 => 20, 3 => 30 }
# Good: one preloaded hash, O(1) per item
total = orders.sum { |id| prices[id] }
puts total

Memoisering

Att beräkna samma kostsamma värde på nytt slösar tid. Memoisera det med ||=.

  • Cacha resultatet efter den första beräkningen
  • Efterföljande anrop returnerar resultatet direkt
class Report
  def total
    @total ||= begin
      puts 'computing...'
      (1..1000).sum
    end
  end
end

r = Report.new
puts r.total
puts r.total

Välj rätt metod

Vissa Enumerable-metoder är mycket snabbare än metodkedjor.

  • sum är snabbare än inject(:+)
  • any? avbryter tidigt, till skillnad från select.empty?
  • find slutar vid den första träffen
nums = (1..1_000_000)
puts nums.any? { |n| n > 5 }
puts nums.find { |n| n > 5 }

Undvik upprepad sortering

Att sortera inuti en loop eller upprepade gånger är kostsamt. Sortera en gång och återanvänd resultatet.

  • Sortering är O(n log n)
  • Cacha det sorterade resultatet om datan är oföränderlig
data = [5, 2, 8, 1, 9]
sorted = data.sort
puts sorted.first
puts sorted.last

Gruppering med hash

group_by och tally aggregerar i ett enda genomlopp i stället för genom upprepade genomgångar.

  • tally räknar förekomster effektivt
  • Undviker manuella räkneloopar
words = ['a', 'b', 'a', 'c', 'b', 'a']
puts words.tally.inspect

Kostnaden för att bygga strängar

Att sammanfoga med join är snabbare än upprepad konkatenering för samlingar.

  • Bygg en array och använd sedan join en gång
  • Undviker många mellanliggande strängar
parts = (1..5).map { |i| "item#{i}" }
puts parts.join(', ')

Kompilering av reguljära uttryck

Om du definierar en regex-literal inuti en intensiv loop kompileras den implicit på nytt. Flytta den till en konstant.

  • Kompilera en gång och matcha många gånger
  • Använd match? när du bara behöver ett booleskt värde
EMAIL = /\A[^@\s]+@[^@\s]+\z/

inputs = ['a@b.com', 'nope', 'x@y.org']
valid = inputs.select { |s| EMAIL.match?(s) }
puts valid.inspect

Fördröjt arbete

Beräkna inte sådant som du kanske aldrig använder. Fördröj det med lat utvärdering eller villkor.

  • Returnera tidigt när det är möjligt
  • Beräkna tunga värden först när de behövs
def describe(items)
  return 'empty' if items.empty?
  "#{items.size} items, first is #{items.first}"
end

puts describe([])
puts describe([10, 20])

Snabbtest

Testa dina kunskaper om flaskhalsar.

Sammanfattning

Du har lärt dig att åtgärda vanliga flaskhalsar:

  • Använd Set eller hash för snabba medlemskapskontroller i stället för include?
  • Eliminera nästlade loopar och N+1-mönster med förladdade hash-tabeller
  • Memoisera kostsamma beräkningar med ||=
  • Välj effektiva metoder (sum, any?, tally) och flytta ut reguljära uttryck
  • Fördröj eller hoppa över arbete som du kanske aldrig behöver utföra

Mät alltid före och efter för att bekräfta förbättringen.

Gratis att börja

Lär dig Ruby med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
29
Lektioner
109

Vanliga frågor

Är lektionen ”Vanliga flaskhalsar” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Ruby Academy, inklusive ”Vanliga flaskhalsar”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Ruby Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Vanliga flaskhalsar”?

Snabba upp Ruby-kod. Ni övar på Ruby Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Ruby Academy?

Du behöver inga förkunskaper. Utbildningen i Ruby Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”Vanliga flaskhalsar”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Ruby Academy-lektionen?

Ja. Varje Ruby Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Mät prestanda
  2. Profileringsverktyg
  3. Minnesoptimering
  4. Vanliga flaskhalsar
← Tillbaka till Ruby Academy