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() - t0Zapobieganie 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 eliminationPoró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))
endBenchmarki 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
- Przegląd architektury LuaJIT
- Pisanie kodu Lua przyjaznego dla JIT
- Profilowanie za pomocą jit.p i perf
- Wzorce benchmarków