0Pricing
Lua Academy · Lekcja

Wzorce benchmarków

Proszę pisać wiarygodne mikrobenchmarki z użyciem os.clock i unikać typowych pułapek.

Wzorce benchmarków to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.

Dlaczego wykonywać benchmarki?

Mikrobenchmarki mierzą wydajność konkretnego fragmentu kodu w izolacji. Pomagają sprawdzić, czy optymalizacja rzeczywiście zwiększa szybkość, bez polegania na intuicji.

Podstawowy szablon benchmarku

Należy umieścić kod w pętli, zmierzyć czas rzeczywisty za pomocą os.clock(), a następnie podzielić go przez liczbę iteracji.

local N = 1e6
local t0 = os.clock()
for i = 1, N do
  -- code to benchmark
end
local elapsed = os.clock() - t0
print(("%.2f ns/op"):format(elapsed / N * 1e9))

Rozgrzewka

Przed pomiarem należy wykonać przebieg rozgrzewkowy, aby umożliwić LuaJIT kompilację śladów. Bez rozgrzewki pierwszy mierzony przebieg obejmuje narzut kompilacji JIT.

for i = 1, 1000 do hotFunction(i) end  -- warm up
local t0 = os.clock()
for i = 1, N do hotFunction(i) end
local elapsed = os.clock() - t0

Zapobieganie eliminacji martwego kodu

JIT może usunąć obliczenia, których wyniki nie są używane. Należy kumulować wyniki w zmiennej, aby benchmark dawał miarodajne wyniki.

local sum = 0
for i = 1, N do sum = sum + math.sin(i) end
print(sum)  -- prevent elimination

Porównywanie dwóch podejść

Alternatywne implementacje należy benchmarkować w identycznych warunkach. Należy uruchamiać je naprzemiennie lub wielokrotnie, aby ograniczyć szum wynikający z planowania zadań przez system operacyjny.

local function approach1() -- ...
end
local function approach2() -- ...
end
local function bench(fn, n)
  local t = os.clock()
  for _ = 1, n do fn() end
  return os.clock() - t
end
print("A:", bench(approach1, 1e5))
print("B:", bench(approach2, 1e5))

Analiza statystyczna

Benchmark należy uruchomić wielokrotnie i obliczyć wartości minimalne, maksymalne oraz medianę. Warto odrzucić wartości odstające wynikające z przerw GC lub planowania zadań przez system operacyjny.

Benchmarkowanie pamięci

Oprócz czasu należy mierzyć także alokację pamięci.

collectgarbage("collect")
local mem0 = collectgarbage("count")
-- ... run operation ...
collectgarbage("collect")
local mem1 = collectgarbage("count")
print(("Memory delta: %.1f KB"):format(mem1 - mem0))

Unikanie zakłóceń powodowanych przez GC

Przed pomiarem należy zatrzymać GC, aby zmierzyć czysty czas obliczeń. Po pomiarze należy je wznowić.

collectgarbage("stop")
local t0 = os.clock()
for i = 1, N do -- ... end
print(os.clock() - t0)
collectgarbage("restart")

Benchmarki realistyczne a mikrobenchmarki

Mikrobenchmarki służą do optymalizowania małych fragmentów, ale mogą nie odzwierciedlać wydajności w rzeczywistych warunkach. Ulepszenia należy zawsze zweryfikować za pomocą profilu całej aplikacji.

Narzędzia do benchmarków

Należy utworzyć wielokrotnego użytku narzędzie benchmark(name, fn, iters), które drukuje spójne i sformatowane wyniki wszystkich benchmarków.

local function benchmark(name, fn, iters)
  iters = iters or 1e5
  for _ = 1, iters // 10 do fn() end  -- warm up
  local t = os.clock()
  for _ = 1, iters do fn() end
  local ns = (os.clock() - t) / iters * 1e9
  print(("%-30s %8.1f ns/op"):format(name, ns))
end

Benchmarki w CI

Benchmarki należy uruchamiać w CI, aby wykrywać regresje wydajności. Należy generować alert, jeśli wynik benchmarku pogorszy się o więcej niż określony próg (np. 10%).

Pytanie dotyczące benchmarków

Dlaczego przebieg rozgrzewkowy jest ważny podczas benchmarkowania kodu LuaJIT?

Podsumowanie: wzorce benchmarkowania

Należy wykonać przebieg rozgrzewkowy, zapobiegać eliminacji martwego kodu przez używanie wyników, mierzyć czas za pomocą os.clock(), kontrolować GC i wykonywać wiele prób, aby uzyskać stabilne pomiary. Dla zachowania spójności warto utworzyć wielokrotnego użytku narzędzie do benchmarków.

Często zadawane pytania

Czy lekcja „Wzorce benchmarków” jest bezpłatna?

Tak — pełny tekst „Wzorce benchmarków” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wzorce benchmarków”?

Proszę pisać wiarygodne mikrobenchmarki z użyciem os.clock i unikać typowych pułapek. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Lua Academy?

Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wzorce benchmarków”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?

Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Przegląd architektury LuaJIT
  2. Pisanie kodu Lua przyjaznego dla JIT
  3. Profilowanie za pomocą jit.p i perf
  4. Wzorce benchmarków
← Powrót do Lua Academy