Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00230 006541 18969015 na godz. na dobę w sumie
C# 7 i .NET Core 2.0. Programowanie wielowątkowych i współbieżnych aplikacji - książka
C# 7 i .NET Core 2.0. Programowanie wielowątkowych i współbieżnych aplikacji - książka
Autor: Liczba stron: 240
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-5044-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> c# - programowanie
Porównaj ceny (książka, ebook (-35%), audiobook).

W świecie programistów aplikacji panuje kult wydajności: najważniejsze są szybkość i efektywność działania kodu. Dostrajanie elementów dużych aplikacji staje się wirtuozerią: wymaga eliminowania wąskich gardeł, optymalizacji kodu, pilnowania każdego bitu pamięci. Niewielkie braki w rozwiązaniach w przypadku rozbudowanych systemów przeradzają się w wielkie problemy. Dla programisty oznacza to, że jeśli chce pracować na prawdziwie profesjonalnym poziomie, musi perfekcyjnie opanować zagadnienia związane ze skalarnością, z modularnością i efektywnością kodu.

Ta książka jest przeznaczona dla programistów .NET, którzy chcą przyspieszyć pracę swoich aplikacji. Opisuje nowe funkcje C# 7 i .NET Core 2.0 oraz ich wpływ na wydajność kodu. Przedstawia takie mechanizmy .NET Core jak proces kompilacji, odzyskiwanie pamięci czy wykorzystywanie wielu rdzeni procesora. Prezentuje koncepcje wielowątkowości i programowania asynchronicznego oraz wyjaśnia znaczenie optymalizacji struktur danych. Omawia też wzorce i najlepsze praktyki projektowania aplikacji w .NET Core, a także zagadnienia bezpieczeństwa i elastyczności oraz architektury mikrousług. Wiedza zawarta w książce pozwoli na pisanie modularnych, skalowalnych, bezpiecznych i niezależnie wdrażanych aplikacji.

W tej książce między innymi:

C# i .NET Core: wielowątkowość - współbieżność - wydajność!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: C# 7 and .NET Core 2.0 High Performance: Build multi threaded and concurrent applications using C# 7 and .Net Core 2.0 Tłumaczenie: Łukasz Świder ISBN: 978-83-283-5044-1 Copyright © Packt Publishing 2018. First published in the English language under the title ‘C# 7 and .NET Core 2.0 High Performance – (9781788470049)’ Polish edition copyright © 2019 by Helion SA All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Helion SA dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Helion SA nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Helion SA ul. Kościuszki 1c, 44-100 Gliwice tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/c7nc2p Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:258)ci O autorze O recenzencie Wst(cid:218)p Rozdzia(cid:239) 1. Co nowego w .NET Core 2 i C# 7? Rozwój frameworka .NET Nowo(cid:258)ci w .NET Core 2.0 Poprawki wydajno(cid:258)ci Uproszczony system pakietów (cid:165)cie(cid:285)ka aktualizacji z .NET Core 1.x do 2.0 1. Instalacja .NET Core 2.0 2. Zaktualizowanie TargetFramework 3. Aktualizacja wersji .NET Core SDK 4. Aktualizacja .NET Core CLI Zmiany w ASP.NET Core Identity Odkrywanie .NET Core CLI i szablonów nowych projektów .NET Standard Wersjonowanie .NET Standard Nowo(cid:258)ci w .NET Standard 2.0 Tworzenie biblioteki .NET Standard Co nowego w ASP.NET Core 2.0? ASP.NET Core Razor Pages Uproszczona konfiguracja Application Insights Pule po(cid:239)(cid:200)cze(cid:241) w Entity Framework Core 2.0 Nowe funkcje w C# 7.0 Krotki Wzorce Zwracanie referencji Rozszerzone wyra(cid:285)enia typu expression bodied member 7 8 9 13 13 15 15 17 17 17 17 18 18 18 18 22 24 25 27 27 27 28 29 29 30 31 32 32 Poleć książkęKup książkę Spis tre(cid:286)ci Tworzenie lokalnych funkcji Zmienne wyj(cid:258)ciowe Asynchroniczna metoda Main Pisanie kodu wysokiej jako(cid:258)ci Podsumowanie Rozdzia(cid:239) 2. Mechanizmy wewn(cid:218)trzne .NET Core i mierzenie wydajno(cid:258)ci Mechanizmy wewn(cid:218)trzne .NET Core CoreFX CoreCLR Dzia(cid:239)anie MSIL, CLI, CTS i CLS Jak dzia(cid:239)a CLR? Od kompilacji do wykonania — pod mask(cid:200) Mechanizm odzyskiwania pami(cid:218)ci (ang. garbage collection) .NET Native i kompilacja JIT Wykorzystywanie wielu rdzeni CPU dla wi(cid:218)kszej wydajno(cid:258)ci Jak kompilacje w trybie wydania zwi(cid:218)kszaj(cid:200) wydajno(cid:258)(cid:202) Testy porównawcze aplikacji .NET Core 2.0 Poznawanie BenchmarkDotNet Jak to dzia(cid:239)a Ustawianie parametrów Diagnostyka pami(cid:218)ci z u(cid:285)yciem BenchmarkDotNet Dodawanie konfiguracji Podsumowanie Rozdzia(cid:239) 3. Wielow(cid:200)tkowo(cid:258)(cid:202) i programowanie asynchroniczne w .NET Core Wielow(cid:200)tkowo(cid:258)(cid:202) kontra programowanie asynchroniczne Wielow(cid:200)tkowo(cid:258)(cid:202) w .NET Core Zastrze(cid:285)enia w wielow(cid:200)tkowo(cid:258)ci W(cid:200)tki w .NET Core Synchronizacja w(cid:200)tków Task parallel library (TPL) Wzorce projektowe programowania równoleg(cid:239)ego Podsumowanie Rozdzia(cid:239) 4. Struktury danych i pisanie zoptymalizowanego kodu C# Czym s(cid:200) struktury danych? Notacja wielkiego O do mierzenia wydajno(cid:258)ci i z(cid:239)o(cid:285)ono(cid:258)ci algorytmu Logarytmy Wybieranie odpowiedniej struktury danych do optymalizacji wydajno(cid:258)ci Tablice Listy Stosy Kolejka Listy (cid:239)(cid:200)czone S(cid:239)owniki, tablice haszuj(cid:200)ce i zbiory haszuj(cid:200)ce Listy generyczne 4 33 33 34 35 38 39 40 40 40 41 42 42 43 46 46 48 49 49 51 51 53 53 55 57 58 60 60 61 64 70 77 83 85 86 88 90 91 91 92 93 94 95 96 96 Poleć książkęKup książkę Spis tre(cid:286)ci Najlepsze praktyki pisania zoptymalizowanego kodu C# Narzut pakowania i rozpakowywania Konkatenacja (cid:239)a(cid:241)cuchów znaków Obs(cid:239)uga wyj(cid:200)tków For i foreach Delegaty Podsumowanie Rozdzia(cid:239) 5. Wytyczne projektowania wydajnych aplikacji .NET Core Zasady kodowania Konwencje nazewnicze Komentarze Jedna klasa na plik Jedna logika na metod(cid:218) Zasady projektowania KISS (Keep It Simple, Stupid) YAGNI (You Aren’t Gonna Need It) DRY (Don’t Repeat Yourself) Podzia(cid:239) odpowiedzialno(cid:258)ci Zasady SOLID Buforowanie Struktury danych Komunikacja Zarz(cid:200)dzanie zasobami Wspó(cid:239)bie(cid:285)no(cid:258)(cid:202) Podsumowanie Rozdzia(cid:239) 6. Techniki zarz(cid:200)dzania pami(cid:218)ci(cid:200) w .NET Core Przegl(cid:200)d zarz(cid:200)dzania alokacj(cid:200) pami(cid:218)ci Analizowanie mechanizmów wewn(cid:218)trznych CLR przez debuger SOS w .NET Core Fragmentacja pami(cid:218)ci Unikanie destruktorów Najlepsze praktyki zwalniania obiektów w .NET Core Wst(cid:218)p do interfejsu IDisposable Czym s(cid:200) niezarz(cid:200)dzane zasoby? Wykorzystywanie IDisposable Kiedy implementowa(cid:202) interfejs IDisposable? Destruktor i Dispose Podsumowanie Rozdzia(cid:239) 7. Stosowanie zabezpiecze(cid:241) i implementowanie odporno(cid:258)ci na b(cid:239)(cid:218)dy w aplikacjach .NET Core Wprowadzenie do aplikacji odpornych na b(cid:239)(cid:218)dy Polityki odporno(cid:258)ci Przechowywanie danych wra(cid:285)liwych z wykorzystaniem Application Secrets Zabezpieczanie API w ASP.NET Core SSL (ang. Secure Socket Layer) Zapobieganie atakom CSRF (ang. Cross-Site Request Forgery) 97 98 100 101 102 103 104 105 106 106 107 107 107 108 108 109 109 109 110 121 122 122 123 124 125 127 128 128 132 133 135 135 135 136 137 138 140 141 142 142 158 161 161 163 5 Poleć książkęKup książkę Spis tre(cid:286)ci Wzmacnianie nag(cid:239)ówków bezpiecze(cid:241)stwa Uwierzytelnianie i autoryzacja Uwierzytelnianie Autoryzacja Implementacja uwierzytelniania i autoryzacji z u(cid:285)yciem frameworka ASP.NET Core Identity Podsumowanie Rozdzia(cid:239) 8. Architektura mikrous(cid:239)ug Architektura mikrous(cid:239)ug Zalety architektury mikrous(cid:239)ug Standardowe praktyki podczas tworzenia mikrous(cid:239)ug Typy mikrous(cid:239)ug DDD Manipulowanie danymi w mikrous(cid:239)ugach Spójno(cid:258)(cid:202) w ró(cid:285)nych scenariuszach biznesowych Komunikacja z mikrous(cid:239)ugami Architektura baz danych w mikrous(cid:239)ugach Czym jest kompozycja API? CQRS Tworzenie architektury mikrous(cid:239)ug w .NET Core Tworzenie przyk(cid:239)adowej aplikacji w .NET Core z wykorzystaniem architektury mikrous(cid:239)ug Wdra(cid:285)anie mikrous(cid:239)ug w kontenerach Docker Czym jest Docker? Korzystanie z Dockera w .NET Core Uruchamianie obrazów Dockera Podsumowanie Rozdzia(cid:239) 9. Monitorowanie wydajno(cid:258)ci aplikacji z wykorzystaniem narz(cid:218)dzi Kluczowe wska(cid:283)niki wydajno(cid:258)ci aplikacji (cid:165)redni czas odpowiedzi Apdex Odsetek b(cid:239)(cid:218)dów Liczba (cid:285)(cid:200)da(cid:241) Przepustowo(cid:258)(cid:202)/punkty ko(cid:241)cowe Wykorzystanie procesora i pami(cid:218)ci Narz(cid:218)dzia i techniki monitorowania wydajno(cid:258)ci Wst(cid:218)p do App Metrics Konfigurowanie App Metrics w ASP.NET Core (cid:165)ledz(cid:200)ce oprogramowanie po(cid:258)rednicz(cid:200)ce Dodawanie raportów graficznych Podsumowanie Skorowidz 6 163 168 169 169 169 173 175 176 177 178 179 179 179 180 181 182 183 184 185 185 210 211 212 214 214 215 216 216 216 216 216 217 217 217 217 217 218 220 229 231 Poleć książkęKup książkę 2 Mechanizmy wewn(cid:218)trzne .NET Core i mierzenie wydajno(cid:258)ci Podczas projektowania architektury aplikacji znajomo(cid:258)(cid:202) wewn(cid:218)trznych mechanizmów plat- formy .NET jest kluczowa dla zagwarantowania jako(cid:258)ci przysz(cid:239)ej aplikacji. W tym rozdziale skupimy si(cid:218) na mechanizmach wewn(cid:218)trznych .NET Core, które mog(cid:200) pomóc nam w pisaniu kodu wysokiej jako(cid:258)ci i tworzeniu wysokiej jako(cid:258)ci architektury dla dowolnej aplikacji. Ten rozdzia(cid:239) poruszy g(cid:239)ówne poj(cid:218)cia zwi(cid:200)zane z mechanizmami wewn(cid:218)trznymi .NET Core, ta- kimi jak: proces kompilacji, mechanizm odzyskiwania pami(cid:218)ci i biblioteka klas platformy (ang. Framework Class Library, FCL). Zako(cid:241)czymy rozdzia(cid:239) przegl(cid:200)dem narz(cid:218)dzia Bench- markDotNet, które jest najcz(cid:218)(cid:258)ciej u(cid:285)ywane do mierzenia wydajno(cid:258)ci aplikacji i jest zalecane do testowania fragmentów kodu w aplikacji. W tym rozdziale poruszymy nast(cid:218)puj(cid:200)ce zagadnienia: (cid:81) Mechanizmy wewn(cid:218)trzne .NET Core (cid:81) Wykorzystywanie wielu rdzeni procesora w celu osi(cid:200)gni(cid:218)cia wysokiej wydajno(cid:258)ci (cid:81) Jak budowanie w trybie wydania zwi(cid:218)ksza wydajno(cid:258)(cid:202) (cid:81) Analiza porównawcza wydajno(cid:258)ci aplikacji .NET Core 2.0 Poleć książkęKup książkę C# 7 i .NET Core 2.0 Mechanizmy wewn(cid:218)trzne .NET Core .Net Core sk(cid:239)ada si(cid:218) z dwóch g(cid:239)ównych komponentów — (cid:258)rodowiska wykonawczego CoreCLR i bibliotek bazowych CoreFX. W tym podrozdziale poruszymy nast(cid:218)puj(cid:200)ce tematy: (cid:81) CoreFX (cid:81) CoreCLR (cid:81) Dzia(cid:239)anie MSIL, CLI, CTS i CLS (cid:81) Jak dzia(cid:239)a CLR? (cid:81) Od kompilacji po wykonanie — pod mask(cid:200) (cid:81) Mechanizm odzyskiwania pami(cid:218)ci (cid:81) .NET Native i kompilacja JIT CoreFX CoreFX jest nazw(cid:200) kodow(cid:200) bibliotek sk(cid:239)adaj(cid:200)cych si(cid:218) na .NET Core. Zawiera wszystkie bi- blioteki zaczynaj(cid:200)ce si(cid:218) s(cid:239)owami Microsoft.* i System.* oraz obejmuje kolekcje, mechani- zmy I/O (wej(cid:258)cia-wyj(cid:258)cia), manipulowanie (cid:239)a(cid:241)cuchami znaków, refleksj(cid:218), zabezpieczenia i wiele innych. CoreFX jest niezale(cid:285)ne od (cid:258)rodowiska wykonawczego i mo(cid:285)e by(cid:202) uruchamiane na ka(cid:285)dej platformie bez wzgl(cid:218)du na to, jakie interfejsy API ona wspiera. Aby pozna(cid:202) wi(cid:218)cej szczegó(cid:239)ów, mo(cid:285)esz odnie(cid:258)(cid:202) si(cid:218) do kodu (cid:283)ród(cid:239)owego .NET Core pod adresem https://source.dot.net. CoreCLR CoreCLR udost(cid:218)pnia wspólne (cid:258)rodowisko wykonawcze dla aplikacji .NET Core i zarz(cid:200)dza pe(cid:239)nym cyklem (cid:285)ycia ka(cid:285)dej aplikacji. Wykonuje wiele operacji podczas dzia(cid:239)ania programu. Operacje takie jak alokowanie pami(cid:218)ci, mechanizm odzyskiwania pami(cid:218)ci, obs(cid:239)uga wyj(cid:200)t- ków, bezpiecze(cid:241)stwo typów, zarz(cid:200)dzanie w(cid:200)tkami oraz bezpiecze(cid:241)stwo s(cid:200) cz(cid:218)(cid:258)ci(cid:200) CoreCLR. (cid:165)rodowisko uruchomieniowe .NET Core zawiera taki sam mechanizm odzyskiwania pami(cid:218)ci (ang. Garbage Collection, GC) jak .NET Framework oraz nowy, bardziej zoptymali- zowany kompilator Just In Time (JIT), zwany RyuJIT. Podczas pierwszego wydania .NET Core obs(cid:239)ugiwa(cid:239) tylko aplikacje w architekturze 64-bitowej, lecz wraz z wydaniem .NET Core 2.0 obs(cid:239)uguje tak(cid:285)e 32-bitowe architektury. Jednak wersja 32-bitowa obs(cid:239)uguje tylko system Windows. 40 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Dzia(cid:239)anie MSIL, CLI, CTS i CLS Podczas budowania projektu kod jest kompilowany do formy j(cid:218)zyka przej(cid:258)ciowego (ang. Intermediate Language, IL), znanego tak(cid:285)e jako j(cid:218)zyk przej(cid:258)ciowy Microsoft (ang. Microsoft Intermediate Language, MSIL). MSIL jest zgodny ze wspóln(cid:200) infrastruktur(cid:200) j(cid:218)zyka (ang. Common Language Infrastructure, CLI), gdzie CLI jest standardem definiuj(cid:200)cym wspólny system typów (Common Type System, CTS) oraz specyfikacj(cid:218) j(cid:218)zyka (Common Language Specification, CLS). CTS zawiera wspólny system typów i kompiluje typy specyficzne dla j(cid:218)zyka na typy zgodne z platform(cid:200). Standaryzuje wszystkie typy j(cid:218)zyków platformy .NET na typy wspólne dla za- pewnienia wspó(cid:239)operacyjno(cid:258)ci j(cid:218)zyka. Przyk(cid:239)adowo, je(cid:258)li kod jest napisany w C#, zostanie przekonwertowany do w(cid:239)a(cid:258)ciwego CTS. Przypu(cid:258)(cid:202)my, (cid:285)e mamy dwie zmienne zdefiniowane w poni(cid:285)szym kodzie C#: class Program { static void Main(string[] args) { int minNo = 1; long maxThroughput = 99999; } } Podczas kompilacji kompilator wygeneruje do podzespo(cid:239)u (ang. Assembly) MSIL, które b(cid:218)dzie dost(cid:218)pne dla CoreCLR, aby wykona(cid:202) JIT i przekonwertowa(cid:202) go na natywny kod maszynowy. Nale(cid:285)y zauwa(cid:285)y(cid:202), (cid:285)e typy int i long s(cid:200) konwertowane na, odpowiednio, int32 i int64: Nie jest wymagane, aby ka(cid:285)dy j(cid:218)zyk by(cid:239) w pe(cid:239)ni zgodny z CTS, mo(cid:285)e obs(cid:239)ugiwa(cid:202) tylko ma(cid:239)y wycinek CTS. Na przyk(cid:239)ad, gdy VB.NET zosta(cid:239) wydany po raz pierwszy w .NET Framework, obs(cid:239)ugiwa(cid:239) tylko typy ca(cid:239)kowitoliczbowe ze znakiem i nie by(cid:239)o mo(cid:285)liwe u(cid:285)ycie typów ca(cid:239)- kowitoliczbowych bez znaku. Z kolejnymi wersjami .NET Framework i teraz z .NET Core 2.0 mo(cid:285)emy do tworzenia aplikacji u(cid:285)ywa(cid:202) wszystkich zarz(cid:200)dzanych j(cid:218)zyków, takich jak C#, F# i VB.NET, i (cid:239)atwo odwo(cid:239)ywa(cid:202) si(cid:218) do ró(cid:285)nych podzespo(cid:239)ów. 41 Poleć książkęKup książkę C# 7 i .NET Core 2.0 Jak dzia(cid:239)a CLR? CLR jest zaimplementowane jako zestaw bibliotek wewn(cid:200)trzprocesowych, które s(cid:200) (cid:239)adowane wraz z aplikacj(cid:200) i dzia(cid:239)aj(cid:200) w ramach kontekstu procesu aplikacji. Na poni(cid:285)szym rysunku wi- dzimy dwie dzia(cid:239)aj(cid:200)ce aplikacje, które zosta(cid:239)y nazwane App1.exe i App2.exe. Ka(cid:285)dy z czarnych kwadratów reprezentuje przestrze(cid:241) adresow(cid:200) aplikacji, wewn(cid:200)trz których App1.exe i App2.exe maj(cid:200) uruchomione ich w(cid:239)asne wersje CLR obok siebie: Podczas pakowania aplikacji .NET Core mo(cid:285)emy je opublikowa(cid:202) albo jako zale(cid:285)ne od frame- worka (ang. Framework Dependent Deployment, FDD), albo jako niezale(cid:285)ne (ang. Self-Contained Deplyments, SCD). W FDD opublikowany pakiet nie posiada (cid:258)rodowiska uruchomieniowego .NET Core i oczekuje, (cid:285)e .NET Core jest zainstalowane w docelowym systemie. Przy SCD wszystkie komponenty, takie jak (cid:258)rodowisko uruchomieniowe .NET Core oraz biblioteki .NET Core, s(cid:200) do(cid:239)(cid:200)czone do opublikowanego pakietu. Dzi(cid:218)ki temu nie jest wymagane, aby docelowy system operacyjny posiada(cid:239) zainstalowane .NET Core. Wi(cid:218)cej informacji o FDD i SCD znajdziesz na stronie pod adresem https://docs.microsoft.com/en-us/ dotnet/core/deploying/. Od kompilacji do wykonania — pod mask(cid:200) Proces kompilacji .NET Core jest podobny do tego w .NET Framework. Podczas konstru- owania projektu system MSBuild, który buduje projekt i generuje bibliotek(cid:218) klas (.dll) lub plik wykonywalny (.exe), wywo(cid:239)uje wewn(cid:218)trzne polecenie .NET CLI. Podzespó(cid:239) zawiera manifest posiadaj(cid:200)cy metadane podzespo(cid:239)u, takie jak numer wersji, j(cid:218)zyk, informacja o refe- rencjach typów, informacja o referencjach do innych podzespo(cid:239)ów oraz list(cid:218) innych plików w podzespole wraz z ich lokalizacj(cid:200). Ten manifest jest przechowywany w kodzie MSIL lub w samodzielnym przeno(cid:258)nym pliku wykonywalnym (ang. Portable executable, PE): 42 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Gdy uruchamiany jest plik wykonywalny, tworzy si(cid:218) nowy proces i (cid:239)aduje (cid:258)rodowisko uru- chomieniowe .NET Core, które potem inicjalizuje (cid:258)rodowisko wykonawcze, konfiguruje stert(cid:218) oraz pul(cid:218) w(cid:200)tków i (cid:239)aduje podzespó(cid:239) do przestrzeni adresowej procesu. Na podstawie kodu programu wywo(cid:239)ywana jest metoda punktu startowego (metoda Main) i wykonywana jest kompilacja JIT. Od tego momentu kod jest wykonywany i obiekty zaczynaj(cid:200) by(cid:202) alo- kowane na stercie, podczas gdy typy proste przechowywane s(cid:200) na stosie. Dla ka(cid:285)dej metody wykonywana jest kompilacja JIT i generowany jest natywny kod maszynowy. Po wykonaniu kompilacji JIT, a przed generowaniem natywnego kodu maszynowego wyko- nywanych jest kilka walidacji. Do tych walidacji zalicza si(cid:218): (cid:81) weryfikowanie, czy MSIL zosta(cid:239) wygenerowany podczas procesu budowania, (cid:81) weryfikowanie, czy kod nie zosta(cid:239) zmodyfikowany lub czy podczas procesu kompilacji JIT nie zosta(cid:239)y dodane nowe typy, (cid:81) weryfikowanie, czy zosta(cid:239) wygenerowany zoptymalizowany kod dla docelowej maszyny. Mechanizm odzyskiwania pami(cid:218)ci (ang. garbage collection) Jedn(cid:200) z najwa(cid:285)niejszych cech CLR jest mechanizm odzyskiwania pami(cid:218)ci. Skoro aplikacje .NET Core s(cid:200) aplikacjami zarz(cid:200)dzanymi, wi(cid:218)kszo(cid:258)(cid:202) procesu odzyskiwania pami(cid:218)ci wykony- wana jest automatycznie przez CLR. Alokacja obiektów w pami(cid:218)ci jest efektywnie wykony- wana przez CLR. CLR nie tylko od czasu do czasu dostosowuje zasoby pami(cid:218)ci wirtualnej, lecz tak(cid:285)e zmniejsza fragmentacj(cid:218) podleg(cid:239)ej pami(cid:218)ci wirtualnej, aby by(cid:239)a bardziej wydajna pod wzgl(cid:218)dem dost(cid:218)pnej przestrzeni. Gdy aplikacja jest wykonywana, obiekty zaczynaj(cid:200) by(cid:202) alokowane na stercie, a adres ka(cid:285)de- go z obiektów przechowywany jest na stosie. Ten proces jest kontynuowany, dopóki pami(cid:218)(cid:202) nie osi(cid:200)gnie swojego maksymalnego limitu. Wtedy do gry wchodzi GC i zaczyna odzyskiwa(cid:202) pami(cid:218)(cid:202) poprzez usuwanie nieu(cid:285)ywanych zarz(cid:200)dzanych obiektów i alokowanie nowych obiek- tów. Wszystko to GC wykonuje automatycznie, lecz mo(cid:285)na te(cid:285) je wywo(cid:239)a(cid:202), aby wykona(cid:239)o od- zyskiwanie pami(cid:218)ci, poprzez wywo(cid:239)anie metody GC.Collect. Na potrzeby przyk(cid:239)adu za(cid:239)ó(cid:285)my, (cid:285)e w metodzie Main mamy obiekt c typu Car. Podczas wykonywania metody obiekt Car b(cid:218)dzie przez CLR zaalokowany w pami(cid:218)ci sterty, a refe- rencja do obiektu c wskazuj(cid:200)ca na adres obiektu Car na stercie zostanie od(cid:239)o(cid:285)ona na stos. 43 Poleć książkęKup książkę C# 7 i .NET Core 2.0 Podczas dzia(cid:239)ania mechanizmu odzyskiwania pami(cid:218)ci odzyskana zostanie pami(cid:218)(cid:202) ze sterty i referencja do obiektu ze stosu zostanie usuni(cid:218)ta: Warty odnotowania jest fakt, (cid:285)e odzyskiwanie pami(cid:218)ci wykonywane jest automatycznie przez GC tylko dla obiektów zarz(cid:200)dzanych i je(cid:258)li mamy jakie(cid:258) obiekty niezarz(cid:200)dzane, jak po(cid:239)(cid:200)czenie z baz(cid:200) danych, operacje wej(cid:258)cia-wyj(cid:258)cia itp., musz(cid:200) by(cid:202) one zwolnione r(cid:218)cznie. Inaczej mówi(cid:200)c, GC dzia(cid:239)a efektywnie dla obiektów zarz(cid:200)dzanych i zapewnia, (cid:285)e aplikacja nie odczuje spadku wydajno(cid:258)ci podczas wykonywania GC. Generacje w GC W odzyskiwaniu pami(cid:218)ci wyró(cid:285)niamy trzy typy generacji, znane jako Generacja 0, Genera- cja 1 i Generacja 2. W tym podrozdziale przyjrzymy si(cid:218) idei generacji i temu, jak wp(cid:239)ywaj(cid:200) one na wydajno(cid:258)(cid:202) odzyskiwania pami(cid:218)ci. Przypu(cid:258)(cid:202)my, (cid:285)e uruchamiamy aplikacj(cid:218) tworz(cid:200)c(cid:200) trzy obiekty nazwane Obiekt1, Obiekt2 i Obiekt3. Obiekty te b(cid:218)d(cid:200) mia(cid:239)y zaalokowan(cid:200) pami(cid:218)(cid:202) w Generacji 0: Gdy odzyskiwanie pami(cid:218)ci zostanie uruchomione (jest to proces automatyczny, chyba (cid:285)e samodzielnie wywo(cid:239)asz go z kodu), sprawdza, czy s(cid:200) obiekty, które nie s(cid:200) ju(cid:285) potrzebne w apli- kacji i nie ma do nich referencji w programie. Takie obiekty zostan(cid:200) po prostu usuni(cid:218)te. 44 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Przyk(cid:239)adowo, je(cid:285)eli nigdzie nie ma odwo(cid:239)ania do zakresu obiektu Obiekt1, pami(cid:218)(cid:202) zajmo- wana przez ten obiekt zostanie odzyskana. Jednak(cid:285)e dwa inne obiekty Obiekt2 i Obiekt3 nadal maj(cid:200) odwo(cid:239)ania w kodzie programu i zostan(cid:200) przeniesione do Generacji 1. Teraz za(cid:239)ó(cid:285)my, (cid:285)e s(cid:200) utworzone dwa kolejne obiekty, zwane Obiekt4 i Obiekt5. Zostan(cid:200) za- kwalifikowane do Generacji 0, co pokazuje poni(cid:285)szy rysunek: Gdy proces odzyskiwania pami(cid:218)ci zostanie uruchomiony po raz drugi, znajdzie dwa obiekty, zwane Obiekt4 i Obiekt5, w Generacji 0 i dwa obiekty, nazywaj(cid:200)ce si(cid:218) Obiekt2 i Obiekt3, w Generacji 1. GC sprawdzi najpierw referencje do obiektów w Generacji 0 i je(cid:258)li nie b(cid:218)d(cid:200) u(cid:285)ywane przez aplikacj(cid:218), zostan(cid:200) usuni(cid:218)te. Tak samo zostan(cid:200) sprawdzone obiekty Generacji 1. Przyk(cid:239)adowo, je(cid:258)li Obiekt3 nadal jest u(cid:285)ywany, zostanie przesuni(cid:218)ty do Generacji 2, a Obiekt2 zostanie usuni(cid:218)ty z Generacji 1, co pokazano na poni(cid:285)szym rysunku. 45 Poleć książkęKup książkę C# 7 i .NET Core 2.0 Koncept generacji optymalizuje prac(cid:218) GC — jest wysoce prawdopodobne, (cid:285)e obiekty prze- chowywane w Generacji 2 b(cid:218)d(cid:200) przechowywane przez d(cid:239)u(cid:285)szy czas. GC wykonuje mniej operacji i dzi(cid:218)ki temu zyskuje czas, zamiast za ka(cid:285)dym razem sprawdza(cid:202) obiekt po obiekcie. To samo tyczy si(cid:218) Generacji 1, dla której tak(cid:285)e odzyskanie pami(cid:218)ci jest mniej prawdopo- dobne ni(cid:285) w przypadku Generacji 0. .NET Native i kompilacja JIT Kompilacja JIT odbywa si(cid:218) w trakcie wykonania i konwertuje kod MSIL do natywnego kodu maszynowego. Odbywa si(cid:218) to podczas pierwszego uruchomienia kodu, które trwa troch(cid:218) d(cid:239)u- (cid:285)ej ni(cid:285) nast(cid:218)pne. W .NET Core tworzymy teraz aplikacje na platformy mobilne i urz(cid:200)dzenia przeno(cid:258)ne, które maj(cid:200) limitowane zasoby procesora oraz pami(cid:218)ci. W przypadku platform Universal Windows Platform (UWP) i Xamarin .NET Core generuje natywny kod w czasie kompilacji lub podczas generowania pakietów specyficznych dla platform. Nie jest przez to wymagana podczas dzia(cid:239)ania kompilacja JIT, co zwi(cid:218)ksza szybko(cid:258)(cid:202) uruchamiania aplikacji. Ta natywna kompilacja wykonywana jest przez komponent zwany .NET Native. NET Native rozpoczyna proces kompilacji zaraz po kompilacji specyficznej dla j(cid:218)zyka pod- czas budowania aplikacji. Mechanizmy .NET Native odczytuj(cid:200) kod MSIL generowany przez kompilator j(cid:218)zyka i przeprowadzaj(cid:200) szereg operacji, m.in.: (cid:81) eliminuj(cid:200) metadane z MSIL, (cid:81) podmieniaj(cid:200) kod bazuj(cid:200)cy na refleksji i metadanych na natywny statyczny kod podczas porównywania warto(cid:258)ci pól, (cid:81) sprawdzaj(cid:200) kod, który ma by(cid:202) wykonany przez aplikacj(cid:218) (i tylko on zostaje w wynikowym podzespole), (cid:81) zamieniaj(cid:200) pe(cid:239)ne CLR na zrefaktoryzowane (cid:258)rodowisko uruchomieniowe z mechanizmem odzyskiwania pami(cid:218)ci i bez kompilatora JIT. Zrefaktoryzowane (cid:258)rodowisko uruchomieniowe zostanie dostarczone wraz z aplikacj(cid:200) i jest zawarte w bibliotece o nazwie mrt100_app.dll. Wykorzystywanie wielu rdzeni CPU dla wi(cid:218)kszej wydajno(cid:258)ci W obecnych czasach aplikacje bazuj(cid:200) bardziej na (cid:239)(cid:200)czno(cid:258)ci i w niektórych przypadkach ope- racje wykonywane przez aplikacj(cid:218) trwaj(cid:200) d(cid:239)u(cid:285)ej. Wiemy tak(cid:285)e, (cid:285)e obecnie wszystkie kompute- ry posiadaj(cid:200) wielordzeniowe procesory i efektywne wykorzystanie tych rdzeni zwi(cid:218)ksza wy- dajno(cid:258)(cid:202) aplikacji. Operacje takie jak sie(cid:202) b(cid:200)d(cid:283) IO maj(cid:200) opó(cid:283)nienia i synchroniczne wykonanie kodu aplikacji mo(cid:285)e prowadzi(cid:202) do d(cid:239)ugich czasów oczekiwania. Je(cid:258)li czasoch(cid:239)onne zadania s(cid:200) wykonywane w oddzielnym w(cid:200)tku lub w sposób asynchroniczny, wykonywana operacja b(cid:218)dzie trwa(cid:202) krócej i wzro(cid:258)nie responsywno(cid:258)(cid:202) aplikacji. Kolejn(cid:200) zalet(cid:200) jest wykonywanie zada(cid:241) na wielu rdzeniach procesora jednocze(cid:258)nie. W (cid:258)wiecie .NET mo(cid:285)emy zyska(cid:202) responsywno(cid:258)(cid:202) i wydajno(cid:258)(cid:202) poprzez podzia(cid:239) zada(cid:241) na wiele w(cid:200)tków, wykorzystuj(cid:200)c klasyczne API progra- 46 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci mowania wielow(cid:200)tkowego lub korzystaj(cid:200)c z uproszczonego i zaawansowanego modelu zna- nego jako task programming library (TPL). TPL jest obs(cid:239)ugiwane przez .NET Core 2.0 i wkrótce przyjrzymy si(cid:218) temu, jak mo(cid:285)e by(cid:202) u(cid:285)yte do wykonywania zada(cid:241) na wielu rdzeniach. Model programowania z wykorzystaniem TPL bazuje na poj(cid:218)ciu zadania. Zadanie jest jed- nostk(cid:200) pracy — obiektowym przedstawieniem operacji w trakcie wykonywania. Proste zadanie mo(cid:285)emy utworzy(cid:202) poprzez napisanie np. poni(cid:285)szego kodu: static void Main(string[] args) { Task t = new Task(Execute); t.Start(); t.Wait(); } private static void Execute() { for (int i = 0; i 100; i++) { Console.WriteLine(i); } } W przedstawionym kodzie zadanie mo(cid:285)e by(cid:202) inicjalizowane z u(cid:285)yciem obiektu typu Task, gdzie Execute jest metod(cid:200) obliczeniow(cid:200), która zostanie wykonana po wywo(cid:239)aniu metody Start. Metoda Start informuje .NET Core, (cid:285)e zadanie mo(cid:285)e zosta(cid:202) wykonane, i ko(cid:241)czy swoje dzia(cid:239)anie. Rozdziela wykonanie programu na dwa w(cid:200)tki, które dzia(cid:239)aj(cid:200) wspó(cid:239)bie(cid:285)nie. Pierwszy w(cid:200)tek to g(cid:239)ówny w(cid:200)tek aplikacji, a drugi wykonuje metod(cid:218) Execute. U(cid:285)yli(cid:258)my metody t.Wait, aby poczeka(cid:202) na w(cid:200)tek roboczy i wy(cid:258)wietli(cid:202) wynik na konsoli. W innym przypadku po opusz- czeniu przez program bloku kodu metody Main aplikacja ko(cid:241)czy dzia(cid:239)anie. Celem programowania równoleg(cid:239)ego jest efektywne wykorzystanie wielu rdzeni procesora. Na przyk(cid:239)ad za(cid:239)ó(cid:285)my, (cid:285)e uruchamiamy podany kod na procesorze jednordzeniowym. Dwa w(cid:200)tki b(cid:218)d(cid:200) dzia(cid:239)a(cid:202) i dzieli(cid:202) ten sam procesor. Je(cid:258)li program by(cid:239)by uruchomiony na proceso- rze wielordzeniowym, móg(cid:239)by dzia(cid:239)a(cid:202) na kilku rdzeniach, wykorzystuj(cid:200)c ka(cid:285)dy rdze(cid:241) od- dzielnie, zwi(cid:218)kszaj(cid:200)c wydajno(cid:258)(cid:202) i osi(cid:200)gaj(cid:200)c prawdziw(cid:200) równoleg(cid:239)o(cid:258)(cid:202): 47 Poleć książkęKup książkę C# 7 i .NET Core 2.0 W przeciwie(cid:241)stwie do TPL, klasyczny obiekt typu Thread nie gwarantuje, (cid:285)e w(cid:200)tek b(cid:218)dzie dzia(cid:239)a(cid:239) na ró(cid:285)nych rdzeniach procesora. TPL daje pewno(cid:258)(cid:202), (cid:285)e ka(cid:285)dy w(cid:200)tek b(cid:218)dzie wykony- wany na innym rdzeniu, chyba (cid:285)e osi(cid:200)gni(cid:218)ta zostanie liczba zada(cid:241) na rdze(cid:241) i rdzenie b(cid:218)d(cid:200) wspó(cid:239)dzielone. Wi(cid:218)cej informacji na temat korzy(cid:258)ci stosowania TPL znajdziesz na stronie pod adresem https://docs. microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl. Jak kompilacje w trybie wydania zwi(cid:218)kszaj(cid:200) wydajno(cid:258)(cid:202) Tryby kompilacji dla wydania (ang. Release) i debugowania s(cid:200) dwoma g(cid:239)ównymi sposobami budowania aplikacji .NET. Tryb debugowania jest u(cid:285)ywany zazwyczaj podczas pisania kodu lub naprawiania b(cid:239)(cid:218)dów, podczas gdy tryb wydania jest cz(cid:218)(cid:258)ciej u(cid:285)ywany podczas pakowa- nia aplikacji do wdro(cid:285)enia na serwerach produkcyjnych. Podczas tworzenia paczki wdro(cid:285)e- niowej programi(cid:258)ci cz(cid:218)sto pomijaj(cid:200) zmian(cid:218) trybu budowania na tryb wydania, przez co po wdro(cid:285)eniu aplikacji pojawiaj(cid:200) si(cid:218) problemy z wydajno(cid:258)ci(cid:200). Poni(cid:285)sza tabela opisuje ró(cid:285)nice pomi(cid:218)dzy trybami debugowania i wydania. Tryb debugowania (Debug) Tryb wydania (Release) Kompilator nie wykonuje optymalizacji kodu (cid:165)lad stosu jest (cid:239)apany i wyrzucany w momencie wyst(cid:200)pienia wyj(cid:200)tku Symbole debugowania s(cid:200) przechowywane Kod (cid:283)ród(cid:239)owy zu(cid:285)ywa wi(cid:218)cej pami(cid:218)ci podczas wykonania Kod jest optymalizowany i zmniejszany jest jego rozmiar podczas budowania w trybie wydania (cid:165)lad stosu nie jest (cid:239)apany Symbole debugowania i ca(cid:239)y kod w ramach dyrektywy #debug s(cid:200) usuwane Kod (cid:283)ród(cid:239)owy zu(cid:285)ywa mniej pami(cid:218)ci podczas wykonania 48 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Testy porównawcze aplikacji .NET Core 2.0 Testowanie porównawcze aplikacji jest procesem oceny i porównywania artefaktów z uzgod- nionymi standardami. Aby wykona(cid:202) testy porównawcze kodu aplikacji .NET Core 2.0, mo- (cid:285)emy u(cid:285)y(cid:202) narz(cid:218)dzia BenchmarkDotNet, które zawiera bardzo proste API do oceny wydaj- no(cid:258)ci kodu aplikacji. Zazwyczaj analiza porównawcza w skali mikro, jak w przypadku klas i metod, nie jest prosta i zmierzenie wydajno(cid:258)ci wymaga wiele wysi(cid:239)ku, podczas gdy BenchmarkDotNet mo(cid:285)e wykona(cid:202) ca(cid:239)e to niskopoziomowe zadanie, jak i z(cid:239)o(cid:285)one zadania zwi(cid:200)zane z analiz(cid:200) porównawcz(cid:200). Poznawanie BenchmarkDotNet W tym podrozdziale poznamy BenchmarkDotNet i nauczymy si(cid:218), jak efektywnie mo(cid:285)emy u(cid:285)y(cid:202) tego narz(cid:218)dzia do mierzenia wydajno(cid:258)ci aplikacji. Mo(cid:285)emy go zainstalowa(cid:202) z u(cid:285)yciem konsoli mened(cid:285)era pakietów NuGet lub poprzez sekcj(cid:218) References projektu. Aby zainstalowa(cid:202) BenchmarkDotNet, nale(cid:285)y wykona(cid:202) polecenie: Install-Package BenchmarkDotNet Powy(cid:285)sze polecenie dodaje pakiet BenchmarkDotNet z NuGet.org. Aby przetestowa(cid:202) narz(cid:218)dzie BenchmarkDotNet, utworzymy prost(cid:200) klas(cid:218), która zawiera dwie metody do generowania sekwencji 10 liczb ci(cid:200)gu Fibonacciego. Ci(cid:200)g Fibonacciego mo(cid:285)e by(cid:202) zaimplementowany na kilka sposobów, dlatego u(cid:285)yjemy go do zmierzenia, który fragment kodu jest szybszy i bardziej wydajny. Oto pierwsza metoda generuj(cid:200)ca ci(cid:200)g Fibonacciego iteracyjnie: public class TestBenchmark { int len = 10; [Benchmark] public void Fibonacci() { int a = 0, b = 1, c = 0; Console.Write( {0} {1} , a, b); for (int i = 2; i len; i++) { c = a + b; Console.Write( {0} , c); a = b; b = c; } } } 49 Poleć książkęKup książkę C# 7 i .NET Core 2.0 Poni(cid:285)ej druga metoda, która wykorzystuje podej(cid:258)cie rekurencyjne do generowania ci(cid:200)gu Fibonacciego: [Benchmark] public void FibonacciRecursive() { int len = 10; Fibonacci_Recursive(0, 1, 1, len); } private void Fibonacci_Recursive(int a, int b, int counter, int len) { if (counter = len) { Console.Write( {0} , a); Fibonacci_Recursive(b, a + b, counter + 1, len); } } Zauwa(cid:285), (cid:285)e obie metody generuj(cid:200)ce liczby ci(cid:200)gu Fibonacciego zawieraj(cid:200) atrybut Benchmark. To w(cid:239)a(cid:258)nie mówi obiektowi BenchmarkRunner, które metody mierzy(cid:202). Mo(cid:285)emy te(cid:285) wywo(cid:239)a(cid:202) BenchmarkRunner z g(cid:239)ównego punktu wej(cid:258)ciowego aplikacji, który to zmierzy wydajno(cid:258)(cid:202) apli- kacji i wygeneruje raport, co pokazano w poni(cid:285)szym fragmencie kodu: static void Main(string[] args) { BenchmarkRunner.Run TestBenchmark (); Console.Read(); } Po uruchomieniu analizy otrzymamy raport podobny do tego: 50 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Zostan(cid:200) równie(cid:285) wygenerowane pliki w g(cid:239)ównym folderze aplikacji uruchamiaj(cid:200)cej Bench (cid:180)markRunner: plik .html zawieraj(cid:200)cy informacje o wersji BenchmarkDotNet, wersji systemu, procesorze, cz(cid:218)stotliwo(cid:258)ci, rozk(cid:239)adzie, szczegó(cid:239)ach licznika, wersji .NET (w naszym przy- padku .NET Core SDK 2.1.4), ho(cid:258)cie i tak dalej: Tabela zawiera cztery kolumny. Mo(cid:285)emy jednak doda(cid:202) wi(cid:218)cej kolumn, które domy(cid:258)lnie s(cid:200) opcjonalne. Mo(cid:285)emy tak(cid:285)e dodawa(cid:202) niestandardowe kolumny. Method to nazwa metody zawieraj(cid:200)cej atrybut Benchmark, Mean jest (cid:258)rednim czasem, który zajmuje wykonanie wszystkich pomiarów (us oznacza milisekundy), Error jest czasem przeznaczonym na przetwarzanie b(cid:239)(cid:218)dów, StdDev jest standardowym odchyleniem pomiarów. Po porównaniu obu metod mo(cid:285)na stwierdzi(cid:202), (cid:285)e metoda FibonacciRecursive jest bardziej wydajna, jako (cid:285)e warto(cid:258)ci dla Mean, Error i StdDev s(cid:200) mniejsze ni(cid:285) dla metody iteracyjnej. Oprócz pliku HTML, tworzone s(cid:200) dwa dodatkowe pliki, plik CSV (ang. Comma Separated Value) oraz plik Markdown (MD), zawieraj(cid:200)ce te same informacje. Jak to dzia(cid:239)a BenchmarkDotNet w czasie dzia(cid:239)ania generuje projekt dla ka(cid:285)dej analizowanej metody oraz buduje go w trybie wydania. Próbuje kilku kombinacji, aby zmierzy(cid:202) wydajno(cid:258)(cid:202) metody po- przez wielokrotne jej wywo(cid:239)ywanie, po czym generuje raport sk(cid:239)adaj(cid:200)cy si(cid:218) z plików i in- formacji o BenchmarkDotNet. Ustawianie parametrów W poprzednim przyk(cid:239)adzie testowali(cid:258)my metod(cid:218) z tylko jedn(cid:200) warto(cid:258)ci(cid:200). W praktyce pod- czas testowania aplikacji klasy enterprise testujemy j(cid:200) z ró(cid:285)nymi warto(cid:258)ciami, aby oszacowa(cid:202) wydajno(cid:258)(cid:202) metody. Po pierwsze, mo(cid:285)emy zdefiniowa(cid:202) w(cid:239)a(cid:258)ciwo(cid:258)(cid:202) dla ka(cid:285)dego parametru poprzez dodanie atrybutu Params i podanie warto(cid:258)ci, dla jakich chcieliby(cid:258)my, aby metoda by(cid:239)a testowana. Pó(cid:283)niej mo(cid:285)emy u(cid:285)y(cid:202) tej w(cid:239)a(cid:258)ciwo(cid:258)ci w kodzie. BenchmarkRun automatycznie testuje metod(cid:218) ze wszystkimi parametrami i generuje raport. Poni(cid:285)ej kompletny kod klasy TestBenchmark: 51 Poleć książkęKup książkę C# 7 i .NET Core 2.0 public class TestBenchmark { [Params(10,20,30)] public int Len { get; set; } [Benchmark] public void Fibonacci() { int a = 0, b = 1, c = 0; Console.Write( {0} {1} , a, b); for (int i = 2; i Len; i++) { c = a + b; Console.Write( {0} , c); a = b; b = c; } } [Benchmark] public void FibonacciRecursive() { Fibonacci_Recursive(0, 1, 1, Len); } private void Fibonacci_Recursive(int a, int b, int counter, int len) { if (counter = len) { Console.Write( {0} , a); Fibonacci_Recursive(b, a + b, counter + 1, len); } } } Po uruchomieniu analizy zostanie wygenerowany raport podobny do poni(cid:285)szego: 52 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Diagnostyka pami(cid:218)ci z u(cid:285)yciem BenchmarkDotNet Z BenchmarkDotNet mo(cid:285)emy tak(cid:285)e diagnozowa(cid:202) dowolne problemy z pami(cid:218)ci(cid:200), procesem odzyskiwania pami(cid:218)ci oraz mierzy(cid:202) liczb(cid:218) alokowanych bajtów. Mo(cid:285)emy to zaimplementowa(cid:202), u(cid:285)ywaj(cid:200)c atrybutu MemoryDiagnoser na poziomie klasy. Dodaj- my atrybut MemoryDiagnoser do klasy TestBenchmark utworzonej w poprzednim przyk(cid:239)adzie: [MemoryDiagnoser] public class TestBenchmark {} Przy ponownym uruchomieniu aplikacji zostan(cid:200) zebrane dodatkowe dane zwi(cid:200)zane z alo- kacj(cid:200) pami(cid:218)ci i procesem odzyskiwania pami(cid:218)ci, a nast(cid:218)pnie odpowiednio umieszczone w raporcie: W powy(cid:285)szej tabeli kolumna Gen 0 oznacza liczb(cid:218) generacji na 1000 operacji. Je(cid:258)li warto(cid:258)ci(cid:200) jest 1, oznacza to, (cid:285)e proces odzyskiwania pami(cid:218)ci mia(cid:239) miejsce po 1000 operacji. Zauwa(cid:285) jednak, (cid:285)e w pierwszym wierszu jest warto(cid:258)(cid:202) 0.1221, która oznacza, (cid:285)e odzyskiwanie pami(cid:218)- ci zosta(cid:239)o wykonane po 0,1221 sekundy, podczas gdy dla tego wiersza nie zosta(cid:239)o przepro- wadzone odzyskiwanie pami(cid:218)ci dla Generacji 1 (w takim wypadku pojawi(cid:239)aby si(cid:218) kolumna Gen 1). Allocated oznacza rozmiar pami(cid:218)ci zaalokowany podczas wywo(cid:239)ywania metody. Nie zawiera natywnych wywo(cid:239)a(cid:241) Stackalloc/heap. Dodawanie konfiguracji Konfiguracja analizy porównawczej mo(cid:285)e by(cid:202) zdefiniowana poprzez utworzenie niestandar- dowej klasy i dziedziczenie z klasy ManualConfig. Oto przyk(cid:239)ad klasy TestBenchmark, któr(cid:200) utworzyli(cid:258)my wcze(cid:258)niej, zawieraj(cid:200)cej metody testowe: [Config(typeof(Config))] public class TestBenchmark { private class Config : ManualConfig { 53 Poleć książkęKup książkę C# 7 i .NET Core 2.0 // B(cid:218)dziemy analizowa(cid:202) TYLKO metody maj(cid:200)ce w nazwie Recursive public Config() { Add(new DisjunctionFilter( new NameFilter(name = name.Contains( Recursive )) )); } } [Params(10, 20, 30)] public int Len { get; set; } [Benchmark] public void Fibonacci() { int a = 0, b = 1, c = 0; Console.Write( {0} {1} , a, b); for (int i = 2; i Len; i++) { c = a + b; Console.Write( {0} , c); a = b; b = c; } } [Benchmark] public void FibonacciRecursive() { Fibonacci_Recursive(0, 1, 1, Len); } private void Fibonacci_Recursive(int a, int b, int counter, int len) { if (counter = len) { Console.Write( {0} , a); Fibonacci_Recursive(b, a + b, counter + 1, len); } } } W powy(cid:285)szym kodzie zdefiniowali(cid:258)my klas(cid:218) Config, która dziedziczy z klasy ManualConfig do- starczanej wraz z bibliotek(cid:200). Regu(cid:239)y mog(cid:200) by(cid:202) zdefiniowane wewn(cid:200)trz konstruktora klasy Config. W przyk(cid:239)adzie wyst(cid:218)puje regu(cid:239)a okre(cid:258)laj(cid:200)ca, (cid:285)e nale(cid:285)y analizowa(cid:202) metody zawieraj(cid:200)ce w nazwie s(cid:239)owo Recursive. W naszym przypadku mamy tylko jedn(cid:200) tak(cid:200) metod(cid:218), FibonacciRecursive, która zostanie wywo(cid:239)ana i której wydajno(cid:258)(cid:202) b(cid:218)dzie zmierzona. 54 Poleć książkęKup książkę Rozdzia(cid:225) 2. • Mechanizmy wewn(cid:266)trzne .NET Core i mierzenie wydajno(cid:286)ci Innym sposobem dodania konfiguracji jest u(cid:285)ycie API fluent, w którym mo(cid:285)emy pomin(cid:200)(cid:202) tworzenie klasy Config i zaimplementowa(cid:202) to w taki sposób: static void Main(string[] args) { var config = ManualConfig.Create(DefaultConfig.Instance); config.Add(new DisjunctionFilter(new NameFilter( name = name.Contains( Recursive )))); BenchmarkRunner.Run TestBenchmark (config); } Wi(cid:218)cej informacji o BenchmarkDotNet znajdziesz pod adresem http://benchmarkdotnet.org/ Configs.htm. Podsumowanie W niniejszym rozdziale poznali(cid:258)my g(cid:239)ówne za(cid:239)o(cid:285)enia .NET Core, w tym procesy kompilacji i odzyskiwania pami(cid:218)ci, dowiedzieli(cid:258)my si(cid:218), jak tworzy(cid:202) wysoko wydajne aplikacje .NET Core poprzez u(cid:285)ycie wielu rdzeni procesora oraz jak publikowa(cid:202) aplikacje w trybie wydania. Przyjrzeli(cid:258)my si(cid:218) równie(cid:285) narz(cid:218)dziu do analizy porównawczej, które jest najcz(cid:218)(cid:258)ciej u(cid:285)ywa- ne do optymalizacji kodu i które dostarcza wyników specyficznych dla klas. W nast(cid:218)pnym rozdziale dowiemy si(cid:218) wi(cid:218)cej o programowaniu wielow(cid:200)tkowym i wspó(cid:239)bie(cid:285)- nym w .NET Core. 55 Poleć książkęKup książkę C# 7 i .NET Core 2.0 56 Poleć książkęKup książkę Skorowidz Application Insights, 28 Secrets, 158 architektura baz danych, 182 logiczna, 187 mikrous(cid:239)ug, 175, 185 zalety, 177 ASP.NET Core, 161 Identity, 18, 169 Razor Pages, 27 ASP.NET Core 2.0, 27 Application Insights, 28 automatyczna kompilacja widoku, 28 Entity Framework Core 2.0, 29 sk(cid:239)adnia Razor, 27 asynchroniczna metoda Main, 34 asynchroniczne operacje, 58 atak CSRF, 163 atomowo(cid:258)(cid:202), 181 automatyczna kompilacja widoku, 28 autoryzacja u(cid:285)ytkowników, 168, 192 B baza danych InfluxDB, 220 per us(cid:239)uga, 183 BCL, Base Class Libraries, 14 BenchmarkDotNet, 49 diagnostyka pami(cid:218)ci, 53 mierzenie wydajno(cid:258)ci, 49 bezpiecze(cid:241)stwo wzmacnianie nag(cid:239)ówków, 163 .NET Core, 22 .NET Core 2, 13 .NET Core CLI, 18 instalacja, 19 polecenia, 20 .NET Core SDK, 18 .NET Framework, 22 .NET Native, 46 .NET Standard, 22 API, 25 tryb kompatybilno(cid:258)ci, 26 tworzenie biblioteki, 27 wersjonowanie, 24 A ACID, Atomicity, Consistency, Integrity, Durability, 181 ACS, Azure Container Service, 175 aktualizacja, 17 alokacja pami(cid:218)ci, 128 analiza porównawcza, 53 Apdex, 216, 218 API, 161 aplikacje ASP.NET Core MVC, 19 odporne na b(cid:239)(cid:218)dy, 142 responsywne, 57 SPAs, 194 APM, Asynchronous Programming Model, 76 App Metrics, 217 konfigurowanie, 217 monitorowanie wydajno(cid:258)ci, 218 (cid:258)ledz(cid:200)ce oprogramowanie po(cid:258)rednicz(cid:200)ce, 219 Poleć książkęKup książkę Skorowidz biblioteka .NET Standard, 27 PCL, 24 biblioteki klas frameworka, FCL, 14 b(cid:239)(cid:218)dy, 142 buforowanie, 121 do(cid:258)wiadczenie u(cid:285)ytkownika, 35 DRY, 109 dzia(cid:239)anie BenchmarkDotNet, 51 CLR, 42 dziedziczenie, 112 C E C# najlepsze praktyki, 97 # 7.0, 13 expression bodied members, 32 krotki, 30 metoda Main, 34 nowe funkcje, 29 tworzenie funkcji, 33 wzorce, 31 zmienne wyj(cid:258)ciowe, 33 zwracanie referencji, 32 CAS, Central Authentication Server, 192 centralny serwer autoryzacji, CAS, 192 CLI, Command Line Interface, 18 CLI, Common Language Infrastructure, 41 CLR, Common Language Runtime, 14, 124, 128 analiza mechanizmów wewn(cid:218)trznych, 128 CLS, Common Language Specification, 41 CoreCLR, 40 CoreFX, 40 CORS, Cross-Origin Resource Sharing, 167, 184 CQRS, Command Query Responsibility Segregation, 180 CRUD, 179 CSRF, Cross-Site Request Forgery, 163 CSV, Comma Separated Value, 51 CTS, Common Type System, 41 cykl (cid:285)ycia w(cid:200)tku, 63 D dane wra(cid:285)liwe, 158 DDD, Domain Driven Design, 178 debuger SOS, 128 debugowanie, 129 delegaty, 103 denormalizacja danych, 180 destruktor, 133, 138 DI, Dependency Injection, 146, 191 diagnostyka pami(cid:218)ci, 53 Docker, 211 uruchamianie obrazów, 214 wdra(cid:285)anie mikrous(cid:239)ug, 210 232 EAP, Event-based Asynchronous Pattern, 76 Entity Framework Core 2.0, 29 F FCL, Framework Class Libraries, 14 FIFO, First In First Out, 94 fragmentacja pami(cid:218)ci, 132 framework .NET, 13 funkcje lokalne, 33 G GC, Garbage Collection, 40 generacje, 44 Grafana instalowanie narz(cid:218)dzia, 223 pulpit nawigacyjny, 223, 225 raportowanie, 227 testowanie aplikacji, 227 I IDE, Integrated Development Environment, 35 IDisposable, 136 implementowanie, 137 implementacja buforowania, 155 interfejsu IDisposable, 137 limitu czasu, 154 sprawdzania stanu zdrowia, 157 TAP, 75 TLS, 165 us(cid:239)ugi dostawców, 202 uwierzytelniania i autoryzacji, 169 Wy(cid:239)(cid:200)cznika obwodu, 145 wzorca Ponawianie, 143 InfluxDB instalowanie, 222 konfigurowanie, 220, 224 pulpit nawigacyjny, 223 Poleć książkęKup książkę instalowanie .NET Core CLI, 19 Grafana, 223 InfluxDB, 222 integralno(cid:258)(cid:202), 181 interfejs IDisposable, 135 konsolowy, CLI, 18 repozytorium, 190 iterowanie, 102 K KISS, 108 klasa, 107 BaseEntity, 189 Startup, 29, 225 TestBenchmark, 51 kolejka, 87, 94 FIFO, 94 kolejkowanie komunikacji, 123 komentarze, 107 kompilacja, 42 w trybie wydania, 48 kompilator JIT, 46 RyuJIT, 16 kompozycja, 113 API, 180, 183 komunikacja, 122 z mikrous(cid:239)ugami, 181 konfiguracja analizy porównawczej, 53 Application Insights, 28 App Metrics, 217 InfluxDB, 220, 224 podsystemu Windows, 221 konkatenacja (cid:239)a(cid:241)cuchów znaków, 100 kontener Docker, 210 konwencje nazewnicze, 106 krotki, 30 L LINQ, 82 listy, 92 cykliczne, 95 dwukierunkowe, 95 generyczne, 96 jednokierunkowe, 95 (cid:239)(cid:200)czone, 87, 95 Skorowidz logarytmy, 90 logika, 107 logowanie, 190 (cid:239)a(cid:241)cuchy znaków, 100 (cid:146) M mapowanie obiektowo-relacyjnego, ORM, 188 maszyna wirtualna, VM, 176 mechanizm odzyskiwania pami(cid:218)ci, GC, 40, 43 mechanizmy wewn(cid:218)trzne, 40 metapakiety, 17 metoda AddDbContextPool, 29 Configure, 225 ConfigureServices, 225 Dispose, 138 Finalize, 138 Main, 34 metody asynchroniczne, 72 pakowania, 98 synchroniczne, 72 mierzenie wydajno(cid:258)ci, 39, 49, 88 mikrous(cid:239)ugi, 175 architektura baz danych, 182 bezstanowe, 179 manipulowanie danymi, 179 opakowywanie, 180 stanowe, 179 tworzenie, 178, 185 wdra(cid:285)anie, 210 minimalizowanie rozmiaru wiadomo(cid:258)ci, 122 model programowania asynchronicznego, APM, 76 modele wdra(cid:285)ania, 15 monitorowanie wydajno(cid:258)ci aplikacji, 217, 215 monitory, 65 MSIL, Microsoft Intermediate Language, 41 MVC, Model View Controller, 14 N nag(cid:239)ówek Content-Security-Policy, 166 referrer-policy, 166 strict transport security, 165 233 Poleć książkęKup książkę Skorowidz nag(cid:239)ówek X-Content-Type-Options, 165 X-Frame-Options, 165 X-Xss-Protection, 166 najlepsze praktyki, 97 zwalnianie obiektów, 135 narz(cid:218)dzia do debugowania, 129 do monitorowania wydajno(cid:258)ci, 217 narz(cid:218)dzie .NET Core CLI, 18 App Metrics, 217 Grafana, 223 narzut pakowania, 98 niezarz(cid:200)dzane zasoby, 135 notacja wielkiego O, 88 O obiekt DbContext, 29 Task, 73 obs(cid:239)uga wyj(cid:200)tków, 101 odzyskiwanie pami(cid:218)ci, 43 opakowywanie mikrous(cid:239)ug, 180 oprogramowanie po(cid:258)rednicz(cid:200)ce (cid:258)ledzenia, 218 optymalizacja wspierana profilem, PGO, 16 ORM, Object-Relational Mapping, 188 P pakiet, 17 NuGet, 20 pami(cid:218)(cid:202) fragmentacja, 132 zarz(cid:200)dzanie alokacj(cid:200), 128 Parallel LINQ, 82 parametry, 111 PCL, Portable Class Libraries, 23 p(cid:218)tla for, 102 foreach, 82, 102 PGO, profile-guided optimization, 16 platformy PCL, 24 plik Markdown, 51 pliki .cs, 107 POCO, Plain Old CLR object, 122, 188 podstawowe biblioteki klas, BCL, 14 podzia(cid:239) baz danych, 183 odpowiedzialno(cid:258)ci, 109 tabel, 183 234 polecenia .NET Core CLI, 20 Entity Framework Core, 21 serwerowe, 21 polityka Fallback, 153 polityki odporno(cid:258)ci, 142 proaktywne, 154 reaktywne, 142 ponawianie, 143, 148, 153 programowanie asynchroniczne, 58 równoleg(cid:239)e, 47 wzorce projektowe, 77 projekt infrastruktury, 189 APIComponents, 191 us(cid:239)ugi to(cid:285)samo(cid:258)ci, 194 projektowanie, 108 przeno(cid:258)ny plik wykonywalny, 42 przep(cid:239)ywy po(cid:239)(cid:200)czenia OpenIddict, 193 pula w(cid:200)tków, 63 R raportowanie, 227 raporty graficzne, 220 referencje, 32 regu(cid:239)y, 37 rozszerzenie SOS, 128 RPM, Request Per Minute, 227 RyuJIT, 16 S s(cid:239)owniki, 96 SOLID, 110 SOS, 128 spójno(cid:258)(cid:202), 180, 181 SSL, Secure Socket Layer, 161 w(cid:239)(cid:200)czanie, 161 sterta, 132 stos, 87, 93 struktura danych, 85, 122 kolejka, 94 lista, 92 generyczna, 96 (cid:239)(cid:200)czona, 95 s(cid:239)ownik, 96 stos, 93 Poleć książkęKup książkę tablica, 91 tablica haszuj(cid:200)ca, 96 zbiór haszuj(cid:200)cy, 96 synchronizacja w(cid:200)tków, 64 system pakietów, 17 szablon projektów, 18 (cid:165) Skorowidz U unikanie destruktorów, 133 URL, Uniform Resource Locator, 194 us(cid:239)uga e-mail, 143 rejestracji u(cid:285)ytkowników, 143 uwierzytelnianie, 168 (cid:258)cie(cid:285)ka aktualizacji, 17 (cid:258)ledz(cid:200)ce oprogramowanie po(cid:258)rednicz(cid:200)ce, 218, 219 V VM, Virtual Machine, 176 T W tabela per us(cid:239)uga, 182 u(cid:285)ytkownika, 171 tablica, 87, 91 haszuj(cid:200)ca, 96 TAP, Task-based asynchronous pattern, 71 TargetFramework, 17 testowanie aplikacji, 227 testy porównawcze, 49 TLS, Transport Level Security, 165 TPL, task parallel library, 70 tworzenie zadania, 70 TPL, task programming library, 47 trwa(cid:239)o(cid:258)(cid:202), 181 tryb debugowania, 48 wydania, 48 tworzenie architektury mikrous(cid:239)ug, 185 biblioteki .NET Standard, 27 domeny sprzedawców, 202 infrastruktury sprzedawców, 204 interfejsu repozytorium, 190 klasy, 189 lokalnych funkcji, 33 mikrous(cid:239)ug, 178 us(cid:239)ugi sprzedawców, 206 us(cid:239)ugi to(cid:285)samo(cid:258)ci, 192 w(cid:200)tków, 61 zadania, 70 typy proste, 86 wiadomo(cid:258)ci, 206 w(cid:200)tki cykl (cid:285)ycia, 63 synchronizacja, 64 w .NET Core, 61 WDK, Windows Driver Kit, 128 wdra(cid:285)anie, 15 mikrous(cid:239)ug, 210 wersjonowanie .NET Standard, 24 w(cid:218)ze(cid:239) Analyzers, 36 wielow(cid:200)tkowo(cid:258)(cid:202), 58 w .NET Core, 60 w(cid:239)(cid:200)czanie CORS, 167 wska(cid:283)nik aktywne (cid:285)(cid:200)dania, 219 Apdex, 216, 218 b(cid:239)(cid:218)dy, 219 czas odpowiedzi, 219 liczba (cid:285)(cid:200)da(cid:241), 216 odsetek b(cid:239)(cid:218)dów, 216 przepustowo(cid:258)(cid:202)/punkty ko(cid:241)cowe, 217 (cid:258)redni czas odpowiedzi, 216 wydajno(cid:258)ci, 216 wykorzystanie procesora i pami(cid:218)ci, 217 wspólne (cid:258)rodowisko uruchomieniowe, CLR, 14 wspó(cid:239)bie(cid:285)no(cid:258)(cid:202), 124 wstrzykiwanie zale(cid:285)no(cid:258)ci, DI, 29, 146, 191 wydajno(cid:258)(cid:202), 15, 39 algorytmu, 88 BenchmarkDotNet, 49 kompilacje w trybie wydania, 48 monitorowanie, 215 narz(cid:218)dzia, 217 programowanie równoleg(cid:239)e, 47 rdzenie CPU, 46 235 Poleć książkęKup książkę Z zabezpieczenia, 141 zadania, 70 anulowanie, 73 raportowanie post(cid:218)pu, 74 status, 73 zajmowanie zasobów, 124 zarz(cid:200)dzanie pami(cid:218)ci(cid:200), 127, 128 zasobami, 123 zasada jednej odpowiedzialno(cid:258)ci, 110 odwrócenia zale(cid:285)no(cid:258)ci, 120 otwarte-zamkni(cid:218)te, 111 podstawienia Liskov, 115 segregacji interfejsów, 117 zasady projektowania, 106, 108 DRY, 109 KISS, 108 SOLID, 110 YAGNI, 109 zbiory haszuj(cid:200)ce, 96 zintegrowane (cid:258)rodowisko deweloperskie, IDE, 35 z(cid:239)o(cid:285)ono(cid:258)(cid:202) programu, 88 zmienne wyj(cid:258)ciowe, 33 zwalnianie obiektów, 124, 135 zwracanie referencji, 32 (cid:191) (cid:285)(cid:200)dania na minut(cid:218), RPM, 227 Skorowidz wydajno(cid:258)(cid:202) RPM, 227 wska(cid:283)niki, 216 wybór struktury danych, 91 wyj(cid:200)tek, 72, 101 Wy(cid:239)(cid:200)cznik obwodu, 148, 153 wyra(cid:285)enia typu expression bodied member, 32 wzorce, 31 projektowe programowania równoleg(cid:239)ego, 77 sta(cid:239)ych, 31 tworzenia obiektów, 120 wzorzec DDD, 178, 179 Fabryka, 120 Jednostka pracy, 189 Mediator, 206 Ponawianie, 143 potoku, 77 producent-konsument, 80 przep(cid:239)ywu danych, 78 typu, 31 var, 32 wstrzykiwanie zale(cid:285)no(cid:258)ci, 120 Wy(cid:239)(cid:200)cznik obwodu, 145 X Y Xamarin, 22 YAGNI, 109 236 Poleć książkęKup książkę
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

C# 7 i .NET Core 2.0. Programowanie wielowątkowych i współbieżnych aplikacji
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: