Profilowanie kodu
Czasami potrzebujemy sprawdzić wydajność jakiegoś fragmentu kodu. Do tego na ogół wykorzystujemy jakiś profiler, np. dotTrace. Ale czasami, gdy chcemy sprawdzić lub porównać szybkość działania jakiegoś rozwiązania, może się okazać, że skorzystanie z takiego dużego profilera jest dość czasochłonne. Dlatego warto wiedzieć, że możemy skorzystać z innych, prostszych narzędzi i nie jest to klasa Stopwatch dostępna w .NET. W tym wpisie pokażę Ci, w jaki sposób wykorzystać do tego bibliotekę o nazwie MiniProfiler (strona biblioteki).
Jak sama nazwa wskazuje, jest to prosta biblioteka, która umożliwia zmierzenie czasu wykonywania jakiegoś fragmentu kodu. Dodatkowo umożliwia łatwą integrację z ASP.NET MVC, dzięki czemu jest przyjemniejsza niż klasa Stopwatch.
Aby skorzystać z biblioteki w ASP.NET MVC, należy zainstalować dwa pakiety z Nugeta:
- MiniProfiler – właściwa biblioteka udostępniająca profilera
- MiniProfiler.MVC4 – pakiet umożliwiający integrację profilera z ASP.NET MVC.
Po zainstalowaniu biblioteki możemy już z niej korzystać. Na potrzeby projektu przygotowałem dwie akcje, które robią to samo, ale w różny sposób – aby można było porównać ich wydajność.
Tworząc aplikację ASP.NET MVC, na ogół wykorzystuję ideę ViewModeli do przekazywania danych z akcji do widoku. W tym wpisie nie będę opisywał, dlaczego to robię zamiast przekazywania samych Modeli. Bardziej skupię się na porównaniu dwóch sposobów mapowania Modeli na ViewModel. Pierwszym będzie ręczne mapowanie obiektów, natomiast drugim będzie wykorzystanie gotowej biblioteki – Automappera. Podobnie jak w przypadku wykorzystywania ViewModeli, nie będę tłumaczył, z czego korzystam w swoich projektach i dlaczego. 🙂
MiniProfiler – przykład
W przykładowym projekcie, który zrobiłem na potrzeby prezentacji, w UsersController znajdują się dwie interesujące nas akcje:
- Index2 – Akcja wykorzystująca Automapper
- Index3 – Akcja wykorzystujące ręczne mapowanie.
Moim celem jest sprawdzenie, jaki narzut ma wykorzystanie Automappera w stosunku do ręcznego mapowania. Właśnie w takich sytuacjach MiniProfiler bardzo fajnie się sprawdza. Wystarczy opakować interesujący fragment blokiem kodu using, w którym na profilerze wywołamy metodę step z opisem kroku – jak to widać poniżej.
public virtual ActionResult Index2() | |
{ | |
using (MiniProfiler.Current.Step("Index2 action")) | |
{ | |
IEnumerable<UserViewModel> viewModels; | |
var models = db.Users.ToList(); | |
using (MiniProfiler.Current.Step("Mapping with automapper")) | |
{ | |
viewModels = Mapper.Map<List<UserViewModel>>(models); | |
} | |
return View(viewModels); | |
} | |
} | |
public virtual ActionResult Index3() | |
{ | |
using (MiniProfiler.Current.Step("Index3 action")) | |
{ | |
IEnumerable<UserViewModel> viewModels; | |
var models = db.Users.ToList(); | |
using (MiniProfiler.Current.Step("Mapping without automapper")) | |
{ | |
viewModels = models.Select(u => new UserViewModel() | |
{ | |
Id = u.Id, | |
Email = u.Email, | |
FirstName = u.FirstName, | |
LastName = u.LastName, | |
CreateInvoice = u.CreateInvoice, | |
UserName = u.UserName, | |
Nip = u.Nip | |
}).ToList(); | |
} | |
return View(Views.Index2, viewModels); | |
} | |
} |
Dzięki temu można fajnie zagnieżdżać poszczególne kroki, aby mieć więcej informacji na temat czasu wykonania poszczególnych kroków akcji.
Pakiet integrujący MiniProfilera z ASP.NET MVC umożliwia wyświetlenie informacji o poszczególnych krokach na samej stronie. Wygląda to tak, jak na poniższych zrzutach ekranu:
Jak widać powyżej, ładnie widoczne są czasy wykonywania się poszczególnych kroków. Co istotne, MiniProfiler pokazuje czas wykonania danego kroku bez kroków potomnych, a to widać na pierwszym zrzucie, gdzie krok z mapowaniem Automappera jest dłuższy niż krok, który mierzy czas wykonania całej akcji.
MiniProfiler domyślnie chowa niektóre kroki, których czas wykonania jest bardzo mały. Na zrzutach widać je jako wyszarzone elementy, które można chować i pokazywać za pomocą przycisku w prawym dolnym rogu.
Aby pokazany wcześniej panel działał w ASP.NET MVC, musimy wykonać dwie rzeczy:
- Musi być w web.config dodany httpHandler:
<add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" /> |
- W jakimś pliku widoku (np. w samym głównym pliku _layout.cshtml, aby mieć funkcjonalność dostępną na każdej stronie) dodajemy kod, który wyświetli panel z informacjami:
@MiniProfiler.RenderIncludes() |
Po tych krokach można się cieszyć z działającego MiniProfilera. Warto pamiętać, że bibliotekę możemy też wykorzystać do innych projektów, nie tylko w ASP.NET MVC.