Użyj Claude Code do badań wydajności z powtarzalną pętlą: zmierz, sformułuj hipotezę, wprowadź małą zmianę i zmierz ponownie przed wdrożeniem.

Błędy wydajnościowe zachęcają do zgadywania. Ktoś zauważa, że strona wydaje się wolna albo API time'uje, a najszybszym ruchem jest „posprzątanie” kodu, dodanie cache'u lub przerobienie pętli. Problem w tym, że „wydaje się wolne” to nie metryka, a „czyściej” nie znaczy „szybciej”.
Bez pomiaru zespoły tracą godziny na zmiany w złym miejscu. Gorąca ścieżka może być w bazie danych, w sieci albo w jednym nieoczekiwanym przydziale pamięci, podczas gdy zespół poleruje kod, który i tak rzadko się uruchamia. Co gorsza, zmiana, która wygląda sprytnie, może pogorszyć wydajność: dodatkowe logowanie w ciasnej pętli, cache zwiększający presję pamięci albo równoległa praca tworząca blokadę.
Zgadywanie też grozi złamaniem działania. Gdy zmieniasz kod, żeby przyspieszyć, możesz zmienić wyniki, obsługę błędów, kolejność lub retry. Jeśli nie sprawdzisz poprawności i wydajności razem, możesz „wygrać” benchmark, jednocześnie wysyłając błąd do produkcji.
Traktuj pracę nad wydajnością jak eksperyment, nie jak spór. Pętla jest prosta i powtarzalna:
Wiele zwycięstw jest skromnych: 8% mniej na p95, 50 MB mniej w piku pamięci albo usunięcie jednego zapytania do DB. Te zwycięstwa mają znaczenie, ale tylko jeśli są zmierzone, zweryfikowane i powtarzalne.
To działa najlepiej jako pętla, nie jednorazowe „przyspiesz to” żądanie. Pętla trzyma cię w ryzach, bo każda akcja odwołuje się do dowodu i liczby, którą możesz obserwować.
Jasna sekwencja:
Każdy krok chroni przed innym rodzajem oszustwa wobec siebie. Pomiar na początku powstrzymuje przed „naprawianiem” czegoś, co nie było prawdziwym problemem. Pisemna hipoteza powstrzymuje przed zmianą pięciu rzeczy naraz i zgadywaniem, która miała wpływ. Minimalne zmiany zmniejszają ryzyko złamania zachowania albo dodania nowych wąskich gardeł. Ponowny pomiar wykrywa placebo (np. szybszy przebieg spowodowany rozgrzanym cache'em) i ujawnia regresje.
„Gotowe” to nie uczucie. To wynik: docelowa metryka poszła w dobrym kierunku, a zmiana nie spowodowała oczywistych regresji (błędy, większa pamięć, gorsze p95 albo wolniejsze sąsiednie endpointy).
Wiedza, kiedy przestać, jest częścią workflow. Przestań, gdy zyski się wypłaszczają, metryka jest już wystarczająca dla użytkowników, albo gdy następny pomysł wymaga dużych refaktorów przy małym zysku. Prace nad wydajnością zawsze mają koszt alternatywny; pętla pomaga wydawać czas tam, gdzie się opłaca.
Jeśli mierzysz pięć rzeczy naraz, nie będziesz wiedział, co się poprawiło. Wybierz jedną metrykę główną dla tej investigacji i traktuj resztę jako sygnały pomocnicze. Dla wielu problemów z interfejsem ta metryka to latencja. Dla pracy batchowej może to być przepustowość, czas CPU, użycie pamięci albo nawet koszt chmury na uruchomienie.
Bądź konkretny co do scenariusza. „API jest wolne” to za mało. „POST /checkout z typowym koszykiem 3 produktów” da się zmierzyć. Utrzymuj stabilne wejścia, by liczby miały sens.
Zapisz baseline i szczegóły środowiska zanim dotkniesz kodu: rozmiar zestawu danych, typ maszyny, tryb budowania, feature flagi, współbieżność i rozgrzewka. Ten baseline jest twoim punktem odniesienia. Bez niego każda zmiana może wyglądać jak postęp.
Dla latencji polegaj na percentylach, nie tylko na średniej. p50 pokazuje typowe doświadczenie, podczas gdy p95 i p99 ujawniają bolesny ogon, na który skarżą się użytkownicy. Zmiana, która poprawia p50, lecz pogarsza p99, wciąż może być odbierana jako wolniejsza.
Zdecyduj wcześniej, co oznacza „istotne”, żeby nie świętować szumu:
Gdy te reguły są ustalone, możesz testować pomysły bez przesuwania celu.
Zacznij od najprostszego sygnału, któremu ufasz. Pojedyncze zmierzenie czasu trwania requestu potrafi powiedzieć, czy masz prawdziwy problem i jak duży on jest. Głębsze profilowanie zostaw, gdy musisz wyjaśnić, dlaczego jest wolno.
Dobry dowód zwykle pochodzi z mieszanki źródeł:
Używaj prostych metryk, gdy pytanie brzmi „czy jest wolniej i o ile?”. Profiluj, gdy pytanie brzmi „gdzie idzie czas?”. Jeśli p95 latency podwoiło się po wdrożeniu, zacznij od timingów i logów, by potwierdzić regresję i określić zasięg. Jeśli timingi pokażą, że większość opóźnienia jest w kodzie aplikacji (a nie w DB), profil CPU lub flame graph mogą wskazać dokładną funkcję, która urosła.
Trzymaj pomiary bezpieczne. Zbieraj to, co potrzebne do debugowania wydajności, nie treści użytkownika. Preferuj agregaty (czasy trwania, liczniki, rozmiary) zamiast surowych payloadów i domyślnie zaciemniaj identyfikatory.
Szum jest realny, więc bierz wiele próbek i notuj outliery. Uruchom ten sam request 10–30 razy i zapisz medianę i p95 zamiast jednego najlepszego przebiegu.
Zapisz dokładny przepis testowy, aby móc go powtórzyć po zmianach: środowisko, zestaw danych, endpoint, rozmiar body, poziom współbieżności i sposób zbierania wyników.
Zacznij od nazwania objawu: „p95 latency skacze z 220 ms do 900 ms w szczytach”, „CPU siedzi na 95% na dwóch rdzeniach” albo „pamięć rośnie o 200 MB na godzinę”. Mglista formułka „wydaje się wolne” prowadzi do losowych zmian.
Następnie przetłumacz co zmierzyłeś na obszar podejrzany. Flame graph może pokazać, że większość czasu idzie na kod JSON, trace może wskazać wolną ścieżkę wywołań, a statystyki DB — jedno zapytanie dominujące łączny czas. Wybierz najmniejszy obszar, który wyjaśnia większość kosztu: funkcję, jedno zapytanie SQL albo jedno zewnętrzne wywołanie.
Dobra hipoteza to jedno zdanie, dające się przetestować i powiązane z przewidywaniem. Proszę o pomoc w przetestowaniu pomysłu, a nie o narzędzie, które „cudownie” przyspieszy wszystko.
Użyj tego formatu:
Przykład: „Ponieważ profil pokazuje 38% CPU w SerializeResponse, przydzielanie nowego bufora na każde żądanie powoduje skoki CPU. Jeśli będziemy ponownie używać bufora, p95 latency powinien spaść o ~10–20% a CPU o ~15% przy tym samym obciążeniu.”
Trzymaj się uczciwości, nazywając alternatywy, zanim dotkniesz kodu. Może wolne jest rzeczywiście upstream, contentacja locków, zmiana hit rate cache'a albo rollout, który zwiększył rozmiar payloadu.
Zapisz 2–3 alternatywne wyjaśnienia i wybierz to, które najlepiej wspiera dowód. Jeśli twoja zmiana nie ruszy metryki, masz już gotową następną hipotezę.
Claude jest najbardziej przydatny, gdy traktujesz go jak starannego analityka, nie wyrocznię. Powiąż każde sugestie z tym, co zmierzyłeś, i upewnij się, że każdy krok można obalić.
Daj mu realne wejścia, a nie mglisty opis. Wklej małe, skupione dowody: podsumowanie profilowania, kilka linii logów wokół wolnego requestu, plan zapytania i konkretną ścieżkę kodu. Dołącz liczby „przed” (p95, CPU, DB time), aby znał baseline.
Poproś o wytłumaczenie, co dane sugerują, a czego nie. Potem wymuś konkurencyjne wyjaśnienia. Warto kończyć promptem: „Podaj 2–3 hipotezy i dla każdej powiedz, co ją sfalsyfikowałoby.” To ogranicza zatrzaśnięcie się przy pierwszej rozsądnej historii.
Zanim zmienisz cokolwiek, poproś o najmniejszy eksperyment, który potwierdzi wiodącą hipotezę. Niech będzie szybki i odwracalny: dodaj jeden timer, włącz jedną flagę profilera albo uruchom EXPLAIN dla zapytania.
Jeśli chcesz ściślejszą strukturę wyników, poproś o:
Jeśli nie jest w stanie nazwać konkretnej metryki, lokalizacji i oczekiwanego wyniku, wracasz do zgadywania.
Mając dowód i hipotezę, powstrzymaj się przed „posprzątaniem wszystkiego”. Prace wydajnościowe są najszybciej zaufane wtedy, gdy zmiana jest mała i łatwa do cofnięcia.
Zmieniaj jedną rzecz na raz. Jeśli poprawiasz zapytanie, dodajesz cache i refaktoryzujesz pętlę w jednym commicie, nie dowiesz się, co pomogło (lub zaszkodziło). Zmiany pojedynczej zmiennej sprawiają, że następny pomiar ma sens.
Zanim dotkniesz kodu, zapisz, czego oczekujesz w liczbach. Przykład: „p95 latency powinien spaść z 420 ms poniżej 300 ms, a czas DB powinien zmaleć o ~100 ms.” Jeśli wynik nie osiągnie celu, szybko uczysz się, że hipoteza była słaba lub niepełna.
Trzymaj zmiany odwracalne:
„Minimalne” nie znaczy „błahe”. Znaczy skupione: cache dla jednej kosztownej funkcji, usunięcie jednego powtarzanego przydziału w ciasnej pętli albo pominięcie pracy dla żądań, które tego nie potrzebują.
Dodaj lekkie timery wokół podejrzanego wąskiego gardła, by zobaczyć, co się ruszyło. Pojedynczy timestamp przed i po wywołaniu (logowany lub zebrany jako metryka) potwierdzi, czy twoja zmiana trafiła w problem, czy tylko przesunęła czas gdzie indziej.
Po zmianie uruchom dokładnie ten sam scenariusz, którego użyłeś w baseline: te same wejścia, środowisko i kształt obciążenia. Jeśli test zależy od cache lub rozgrzewki, sprecyzuj to (np. „pierwszy przebieg zimny, następne 5 ciepłe”). W przeciwnym razie „znajdziesz” poprawy będące przypadkiem.
Porównuj wyniki używając tych samych metryk i percentyli. Średnie mogą ukrywać ból – obserwuj p95 i p99 oraz throughput i czas CPU. Wykonaj wystarczającą liczbę powtórzeń, by zobaczyć stabilizację liczb.
Zanim będziesz świętować, sprawdź regresje, które niekoniecznie widać w jednym nagłówkowym numerze:
Następnie decyduj na podstawie dowodu, nie nadziei. Jeśli poprawa jest realna i nie wprowadziła regresji, zostaw ją. Jeśli wyniki są mieszane lub hałaśliwe, cofnij i sformułuj nową hipotezę albo jeszcze bardziej odizoluj zmianę.
Jeśli pracujesz na platformie takiej jak Koder.ai, wykonanie snapshotu przed eksperymentem może uczynić rollback prostym krokiem, co ułatwia bezpieczne testowanie odważnych pomysłów.
Na koniec zapisz, czego się nauczyłeś: baseline, zmiana, nowe liczby i wniosek. Krótka notatka zapobiega powtórzeniu tych samych ślepych zaułków w następnej rundzie.
Prace nad wydajnością zazwyczaj idą w bok, gdy tracisz ciągłość między tym, co zmierzyłeś, a tym, co zmieniłeś. Trzymaj czysty łańcuch dowodów, aby móc z pewnością powiedzieć, co poprawiło lub pogorszyło sytuację.
Najczęstsze przewinienia:
Mały przykład: endpoint wygląda na wolny, więc stroisz serializator, bo jest gorący w profilu. Testujesz ponownie na mniejszym zestawie i wydaje się szybszy. W produkcji p99 się pogarsza, bo DB nadal jest wąskim gardłem, a twoja zmiana powiększyła payload.
Jeśli używasz Claude Code do proponowania poprawek, trzymaj go krótko na smyczy. Poproś o 1–2 minimalne zmiany, które pasują do zebranego dowodu i nalegaj na plan ponownego pomiaru przed akceptacją patcha.
Twierdzenia o szybkości rozpadają się, gdy testy są niejasne. Zanim świętujesz, upewnij się, że możesz wytłumaczyć, co mierzyłeś, jak to mierzyłeś i co zmieniłeś.
Zacznij od nazwania jednej metryki i zapisania baseline'u. Uwzględnij szczegóły, które zmieniają liczby: typ maszyny, obciążenie CPU, rozmiar danych, tryb builda (debug vs release), feature flagi, stan cache i współbieżność. Jeśli nie potrafisz odtworzyć setupu jutro, nie masz baseline'u.
Checklista:
Gdy liczby wyglądają lepiej, zrób szybki pass regresyjny. Sprawdź poprawność (te same outputy), rate błędów i timeouty. Obserwuj efekty uboczne jak większa pamięć, skoki CPU, wolniejszy start czy większe obciążenie DB. Zmiana, która poprawia p95, ale podwaja pamięć, może być złą wymianą.
Zespół zgłasza, że GET /orders jest w porządku w dev, ale zwalnia na staging przy umiarkowanym obciążeniu. Użytkownicy skarżą się na timeouty, ale średnia latencja wygląda „w porządku”, co jest klasyczną pułapką.
Najpierw ustal baseline. Przy stabilnym teście obciążeniowym (te same dane, ta sama współbieżność, ten sam czas) zapisujesz:
Zbierz dowody. Szybki trace pokazuje, że endpoint wykonuje główne zapytanie o zamówienia, potem w pętli pobiera powiązane elementy dla każdego zamówienia. Widzisz też, że JSON jest duży, ale czas DB dominuje.
Przekształć to w listę hipotez do przetestowania:
Poproś o minimalną zmianę pasującą do najsilniejszego dowodu: usuń oczywiste N+1, pobierając elementy jednym zapytaniem kluczowanym po order ID (albo dodaj brakujący indeks, jeśli plan zapytania pokazuje pełne skanowanie). Trzymaj to odwracalnym i w jednym, skupionym commicie.
Zmierz ponownie tym samym testem obciążeniowym. Wyniki:
Decyzja: wdrażamy poprawkę (wyraźna wygrana), potem startujemy drugą pętlę skupioną na pozostałym rozdźwięku i skokach CPU, bo DB już nie jest głównym ograniczeniem.
Najszybsza droga do poprawy w badaniach wydajności to traktowanie każdej rundy jak mały, powtarzalny eksperyment. Gdy proces jest spójny, wyniki stają się łatwiejsze do zaufania, porównywania i udostępniania.
Prosty, jednoplacowy szablon pomaga:
Zdecyduj, gdzie przechowywać te notatki, żeby nie zniknęły. Wspólne miejsce jest ważniejsze niż idealne narzędzie: folder w repo obok serwisu, dokument zespołowy lub notatki w tickecie. Klucz to odnajdywalność. Ktoś powinien móc znaleźć „p95 spike po zmianie cache” miesiące później.
Uczyń bezpieczne eksperymenty nawykiem. Używaj snapshotów i prostego rollbacku, by móc przetestować pomysł bez strachu. Jeśli budujesz z Koder.ai, Planning Mode może być wygodnym miejscem na zarys planu pomiaru, zdefiniowanie hipotezy i utrzymanie zakresu przed wygenerowaniem zwartego diffu i ponownym pomiarem.
Ustal rytm. Nie czekaj na incydenty. Dodawaj małe checki wydajności po zmianach, takich jak nowe zapytania, endpointy, większe payloady lub aktualizacje zależności. 10-minutowy baseline teraz może zaoszczędzić dzień zgadywania później.
Zacznij od jednej liczby, która odpowiada skardze — zazwyczaj p95 latency dla konkretnego endpointu i zestawu wejściowego. Zapisz baseline w tych samych warunkach (rozmiar danych, współbieżność, stan cache: zimny/ciepły), potem zmień jedną rzecz i zmierz ponownie.
Jeśli nie potrafisz odtworzyć baseline'u, to jeszcze nie mierzysz — zgadujesz.
Dobry baseline zawiera:
Zapisz to, zanim dotkniesz kodu, żeby nie przesuwać celu.
Percentyle lepiej odzwierciedlają doświadczenie użytkownika niż średnia. p50 pokazuje „typowe” doświadczenie, ale użytkownicy narzekają na ogon, czyli p95/p99.
Jeśli p50 się poprawia, a p99 się psuje, system może się wydawać wolniejszy mimo lepszej średniej.
Używaj prostych pomiarów/logów, gdy pytasz „czy jest wolniej i o ile?”. Profiluj, gdy pytasz „gdzie idzie czas?”.
Praktyczna ścieżka: potwierdź regresję prostymi timingami, a profilowanie włącz dopiero gdy wiesz, że spowolnienie jest realne i zasięg jest określony.
Wybierz jedną metrykę główną i traktuj resztę jako strażników. Typowy zestaw:
To zapobiega „wygrywaniu” jednego wykresu kosztem timeoutów, wzrostu pamięci czy gorszego ogona latency.
Napisz jednozdaniową hipotezę powiązaną z dowodem i przewidywaniem:
Jeśli nie potrafisz wskazać dowodu i spodziewanego ruchu metryki, hipoteza nie jest testowalna.
Rób to małe, wąskie i łatwe do odwrócenia:
Małe diffy sprawiają, że kolejny pomiar ma sens i zmniejszają ryzyko złamania zachowania przy jednoczesnym dążeniu do szybkości.
Uruchom ten sam scenariusz, którego użyłeś jako baseline: te same wejścia, środowisko i wzorzec obciążenia. Jeśli test zależy od cache/warm-up, to to jawnie określ (np. „pierwsze uruchomienie zimne, kolejne 5 uruchomień ciepłe”). W przeciwnym razie będziesz „znajdować” poprawę, która jest po prostu szczęściem.
Porównuj te same percentyle. Średnie mogą ukrywać ból — patrz na p95 i p99 oraz CPU/throughput. Zrób wystarczającą liczbę powtórzeń, by zobaczyć ustabilizowanie się liczb.
Zanim świętujesz, sprawdź regresje: poprawność wyników, rate błędów, pamięć, ogon latency (p99) i skoki obciążenia zasobów. Jeśli poprawa jest realna i bez regresji, wdrażaj; jeśli wyniki są mieszane lub hałaśliwe, cofnij i sformułuj nową hipotezę.
Daj mu konkretne dane, a nie mglisty opis. Wklej krótkie, skupione dowody: podsumowanie profilera, kilka linii logów wokół wolnego requestu, plan zapytania i konkretną ścieżkę kodu. Dołącz „przed” liczby (p95, CPU, DB time), żeby miał baseline.
Poproś, żeby wyjaśnił, co dane sugerują, a czego nie. Zmuszaj do konkurencyjnych wyjaśnień. Przydatne polecenie: „Podaj 2–3 hipotezy i dla każdej powiedz, co ją sfalsyfikowałoby.” To zapobiega utkwieniu w pierwszym sensownym wytłumaczeniu.
Przed wprowadzeniem zmian poproś o najmniejszy eksperyment weryfikujący hipotezę — szybki i odwracalny: dodanie timera, włączenie flagi profilera, uruchomienie EXPLAIN na zapytaniu.
Jeśli wynik nie zawiera konkretnej metryki, lokalizacji i planu ponownego pomiaru, wracasz do zgadywania.
Przed nazwaniem „szybsze” upewnij się, że możesz wytłumaczyć, co zmierzyłeś, jak to zmierzyłeś i co zmieniłeś.
Lista kontrolna przed świętowaniem:
Po poprawie zrób szybkie sprawdzenie regresji: poprawność, rate błędów, timeouty, skoki pamięci lub CPU. Zmiana, która poprawia p95, a jednocześnie podwaja pamięć, może być złą wymianą.