Korzystając z wyrażenia profile, możesz wykorzystać kod do tego, aby mierzył swoją wydajność. Poniżej możesz zapoznać się ze składnią, która umożliwia wykorzystanie wyrażenia profile w bloku kodu.
code-before
profile:
code-to-measure
code-afterW tym przykładzie slow-code reprezentuje blok kodu, którego wydajność użytkownik chce zmierzyć. Po uruchomieniu kodu w dzienniku wyjściowym w UEFN jest zapisywany czas (w milisekundach), który upłynął między wejściem a wyjściem z bloku kodu profile.
Dane wyjściowe dla kodu są profilowane jako LogVerse: VerseProfile: 0.023900 ms. Jeśli kod zawiera wiele wyrażeń profilujących i chcesz uporządkować dane wyjściowe, możesz do wyrażenia profilującego dodać ciąg tekstowy (string) jako tagi użytkownika:
profile(“User String to Categorize Output”):
code-to-measureW tym przykładzie dane wyjściowe wyglądałyby w następujący sposób: LogVerse: VerseProfile: Ciąg tekstowy użytkownika do porządkowania danych wyjściowych 0.023900 ms.
Jeśli korzystasz z wyrażenia profile w kontekście niepowodzenia, który obejmuje również zapisy w dzienniku, wszystkie dane wyjściowe dotyczące profilowania są zgłaszane przed zapisami w dzienniku wyjściowym, niezależnie od kolejności wyrażeń profile i wywołań zapisu zawartych w kodzie.
Jeśli blok kodu profile zawiera wyrażenie defer, wyrażenie defer również będzie profilowane, ale zostanie uruchomione jako ostatnie przy wychodzeniu z bloku kodu profile.
MyFunction1():void=
defer:
MyFunction2() # code is not profiled
profile:
defer:
MyFunction3() # code is profiled and run last
MyFunction4() # code is profiled and run firstWynik
Wszystko w Verse jest wyrażeniem, co oznacza, że ma jakiś wynik. Dotyczy to również wyrażenia profile. Wartości wynikowe przechodzą przez wyrażenie profile w taki sam sposób jak przez wyrażenia if.
W tym przykładzie MyFunction zwraca jakąś wartość, która przechodzi przez wyrażenie profile i jest przechowywana w zmiennej ResultOfFunction. Oznacza to, że możesz ułatwić instrumentację kodu wokół wywołań funkcji i wykorzystać wyniki wywołań funkcji poza zakresem profilowania bloku kodu.
ResultOfFunction := profile(“MyFunction”):
MyFunction()Wskazówki i dobre praktyki
Pracując z wyrażeniem profile, należy mieć na uwadze następujące wskazówki i dobre praktyki:
Czasy wskazywane przez wyrażenia
profilenie są deterministyczne dla określonego fragmentu kodu. Rzeczywisty zmierzony czas może zależeć od wielu czynników pozostających poza Twoją kontrolą, takich jak stan gry, liczba graczy, obciążenie serwera, opóźnienie sygnału sieciowego itd. Najlepiej jest wielokrotnie sprofilować określony fragment kodu, aby wyznaczyć najlepsze, średnie i najgorsze przypadki, a także w celu zrozumienia, które punkty danych są wartościami odstającymi.Profilowanie powoduje niewielki dodatkowy nakład pracy, które wynika głównie z dokonywania wpisów w dzienniku i interpolowania ciągu tekstowego dla tagu użytkownika. Może to nieznacznie zwiększyć wartość czasu będącą wynikiem profilowania, dlatego należy skierować profilowanie na konkretne obszary, którymi się interesujesz, i zadbać, aby tagi użytkownika były proste.
Należy unikać zagnieżdżania wyrażeń
profile. To zadziała, ale nakład pracy wynikający z profilowania wewnętrznego wyrażeniaprofilezostanie uwzględniony w czasie zmierzonym dla zewnętrznego wyrażeniaprofilei będzie miał wpływ na wyniki.Należy usunąć wyrażenia
profilez kodu gry do dostarczenia. Generowanie kodu profilującego nie jest obecnie wykluczone w wersjach do dostarczenia, dlatego pozostawienie takiego kodu spowodowałoby niepożądany nakład pracy kodu w trakcie gry.
Znane ograniczenia
Oto znane ograniczenia związane z korzystaniem z wyrażenia profile.
Można korzystać z wyrażenia profile w kontekście asynchronicznym, ale obecnie nie można wywoływać kodu asynchronicznego w bloku kodu profile. Ilustruje to poniższy przykład.
MyAsyncFunction()<suspends>:void=
profile: # Allowed inside <suspends> function
MyRandomInt := GetRandomInt(10, 100) # Allowed inside profile
Sleep(0.0) # Not allowed inside profileNie można korzystać z wyrażenia profile wraz z inicjalizacją statycznych danych składowych klasy. Następujący przykład jest niedozwolony.
my_class := class:
Value:int = profile{ 1 + 2 + 3 }