Blog (22)
Komentarze (619)
Recenzje (0)

O wydajności w aplikacjach .NET

@alucosoftwareO wydajności w aplikacjach .NET16.02.2012 00:52

Coraz częściej użytkownicy vortalu dobreprogramy opisują ulubione narzędzia programistyczne i wykorzystywane do różnorakich celów języki programowania. Takie wpisy budzą całkiem spore zainteresowanie wśród czytelników dobrychprogramów. Niemniej czytając komentarze pod wybranymi wpisami odnosi się wrażenie nieustannej bitwy ideologicznej, której stronami są zwolennicy tradycyjnych rozwiązań tj. programowania natywnego z wykorzystaniem języków pokroju C/C++ oraz zwolennicy kodu zarządzanego przez maszyny wirtualne (np. JVM dla Javy, CLR dla C# i pozostałych).

Nierzadko podejmowaną kwestią w tych burzliwych dyskusjach jest wydajność tworzonych aplikacji w zależności od wybranej technologii. Ech... ta wydajność... termin określający niepotrzebną bolączkę programistów naszych czasów.

W codziennej pracy wykorzystuję kilka narzędzi programistycznych z .NET'em na czele. Zaryzykuję stwierdzenie, że w dobie komputerów o tak znaczących mocach obliczeniowych i doskonale zoptymalizowanych procesów kompilacji i wykonywania kodu zarządzanego aplikacje działające w ramach platformy .NET nie ustępują tradycyjnym rozwiązaniom. Przynajmniej w przeważającej większości przypadków zastosowań.

Musicie bowiem zgodzić się z tym, że - biorąc pod uwagę wszelkie udogodnienia wprowadzone w ramach kodu zarządzanego - responsywność oprogramowania mierzona subiektywnym odczuciem użytkownika programu nie różni się od tej, którą oferuje nam świat "niebezpiecznych wskaźników i wycieków pamięci" (celowo w cudzysłowie).

Jedno ale

Taki stan rzeczy uzyskamy tylko pod warunkiem bezwzględnego przestrzegania zasad, zaleceń czy też inaczej wzorców i praktyk określonych przez producenta danej platformy programistycznej - tu Microsoftu. Potocznie konkludując, jeśli bardziej niż treści oferowane przez MSDN cenisz niby-programistyczne podejście typu google-kopiuj-wklej-it works! to sorry, ale demonami szybkości twoje aplikacje nigdy nie będą, a i przekonań się złych nabawisz.

Studia, te wyższe i te niższe, z całą swą przebojowością mają z natury nie uczyć, lecz wskazać drogę właściwego korzystania ze źródeł, wszelakich, nie tylko tych określonych w podstawie programowej. Jako programiści popełniamy błędy wielokrotnie, ale błędem kardynalnym jest niechęć do korzystania z ogólnodostępnej bazy wiedzy oferowanej przez producenta lub uznawanie jej za zbędną.

Niniejszy tekst rozpoczyna cykl wpisów traktujących o wydajności w aplikacjach .NET. Bardzo skromnie i na przykładach postaram się przybliżyć wam wybrane, lecz z całą pewnością nie wszystkie, zagadnienia wpływające na wydajność kodu zarządzanego. Jeśli gdziekolwiek się pomylę, poprawcie mnie. A jeśli wykorzystujecie inne technologie (np. Java), spróbujcie przenieść stosowną część przedstawionych tu treści na swoje ulubione platformy i poinformujcie nas o swoich rezultatach.

Na wstępie rozważań warto by określić na czym, pod pojęciem wydajności, najbardziej nam zależy. Niech na potrzeby niniejszego cyklu wskaźnikiem tym będzie szybkość wykonywania kodu. Aby umożliwić wszystkim zainteresowanym wykonywanie podobnych pomiarów na niedotnetowych platformach działających pod kontrolą systemu Windows, jako podstawowe narzędzie pomiarowe wykorzystam funkcję QueryPerformanceCounter oraz QueryPerformanceFrequency dotępne w Win32 API. Dokładność QueryPerformanceCounter jest rzędu nanosekundy. Zbliżoną do niej funkcjonalność w środowisku .NET Framework 2.0 i wyżej zapewnia klasa StopWatch w przestrzeni nazw System.Diagnostics (ekhm, dokładnie taką samą).

W programowaniu unikam mieszania języków polskiego i angielskiego, dlatego trzymam się konwencji stosowania angielskich nazw dla klas, obiektów i innych reprezentujących kluczowe elementy kodu źródłowego.

Prosta implementacja QueryPermormanceCounter w kodzie zarządzanym (C#), czyli tzw. klasa opakowująca (prawda, że "wrapper" brzmi lepiej?), którą będziemy notorycznie wykorzystywali w przyszłości wygląda następująco:


using System;
using System.Text;
using System.ComponentModel;
using System.Security;
using System.Runtime.InteropServices;

namespace TestPerformance1
{
    class Program
    {
        static void Main(string[] args)
        {
            PerformanceCounter counter = new PerformanceCounter();

            counter.Start();
            Console.WriteLine("Test wydajności...\n");
            counter.Stop();

            Console.WriteLine("Czas trwania testu:\n{0:F3} ns\n{1:F3} ms\n", counter.ElapsedNanoseconds, counter.ElapsedMiliseconds);
        }
    }

    class PerformanceCounter
    {
        [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
        [DllImport("kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long lpFrequency);

        private long start;
        private long stop;
        private long frequency;
        Decimal nanoMultiplier = new Decimal(1.0e9);
        Decimal miliMultiplier = new Decimal(1.0e3);

        public PerformanceCounter()
        {
            // Więcej informacji na:
            // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx

            if (QueryPerformanceFrequency(out frequency) == false)
                throw new Win32Exception();
        }

        public void Start()
        {
            QueryPerformanceCounter(out start);
        }

        public void Stop()
        {
            QueryPerformanceCounter(out stop);
        }

        public double ElapsedNanoseconds
        {
            get { return (((double)(stop - start) * (double)nanoMultiplier) / (double)frequency); }
        }

        public double ElapsedMiliseconds
        {
            get { return (((double)(stop - start) * (double)miliMultiplier) / (double)frequency); }
        }
    }
}

Sprawdźcie czy działa, pobawcie się. Zwróćcie uwagę na atrybut SuppressUnmanagedCodeSecurity. Niebawem wykorzystamy naszą klasę w bardziej racjonalny sposób.

Szanowna Użytkowniczko! Szanowny Użytkowniku!
×
Aby dalej móc dostarczać coraz lepsze materiały redakcyjne i udostępniać coraz lepsze usługi, potrzebujemy zgody na dopasowanie treści marketingowych do Twojego zachowania. Twoje dane są u nas bezpieczne, a zgodę możesz wycofać w każdej chwili na podstronie polityka prywatności.

Kliknij "PRZECHODZĘ DO SERWISU" lub na symbol "X" w górnym rogu tej planszy, jeżeli zgadzasz się na przetwarzanie przez Wirtualną Polskę i naszych Zaufanych Partnerów Twoich danych osobowych, zbieranych w ramach korzystania przez Ciebie z usług, portali i serwisów internetowych Wirtualnej Polski (w tym danych zapisywanych w plikach cookies) w celach marketingowych realizowanych na zlecenie naszych Zaufanych Partnerów. Jeśli nie zgadzasz się na przetwarzanie Twoich danych osobowych skorzystaj z ustawień w polityce prywatności. Zgoda jest dobrowolna i możesz ją w dowolnym momencie wycofać zmieniając ustawienia w polityce prywatności (w której znajdziesz odpowiedzi na wszystkie pytania związane z przetwarzaniem Twoich danych osobowych).

Od 25 maja 2018 roku obowiązuje Rozporządzenie Parlamentu Europejskiego i Rady (UE) 2016/679 (określane jako "RODO"). W związku z tym chcielibyśmy poinformować o przetwarzaniu Twoich danych oraz zasadach, na jakich odbywa się to po dniu 25 maja 2018 roku.

Kto będzie administratorem Twoich danych?

Administratorami Twoich danych będzie Wirtualna Polska Media Spółka Akcyjna z siedzibą w Warszawie, oraz pozostałe spółki z grupy Wirtualna Polska, jak również nasi Zaufani Partnerzy, z którymi stale współpracujemy. Szczegółowe informacje dotyczące administratorów znajdują się w polityce prywatności.

O jakich danych mówimy?

Chodzi o dane osobowe, które są zbierane w ramach korzystania przez Ciebie z naszych usług, portali i serwisów internetowych udostępnianych przez Wirtualną Polskę, w tym zapisywanych w plikach cookies, które są instalowane na naszych stronach przez Wirtualną Polskę oraz naszych Zaufanych Partnerów.

Dlaczego chcemy przetwarzać Twoje dane?

Przetwarzamy je dostarczać coraz lepsze materiały redakcyjne, dopasować ich tematykę do Twoich zainteresowań, tworzyć portale i serwisy internetowe, z których będziesz korzystać z przyjemnością, zapewniać większe bezpieczeństwo usług, udoskonalać nasze usługi i maksymalnie dopasować je do Twoich zainteresowań, pokazywać reklamy dopasowane do Twoich potrzeb. Szczegółowe informacje dotyczące celów przetwarzania Twoich danych znajdują się w polityce prywatności.

Komu możemy przekazać dane?

Twoje dane możemy przekazywać podmiotom przetwarzającym je na nasze zlecenie oraz podmiotom uprawnionym do uzyskania danych na podstawie obowiązującego prawa – oczywiście tylko, gdy wystąpią z żądaniem w oparciu o stosowną podstawę prawną.

Jakie masz prawa w stosunku do Twoich danych?

Masz prawo żądania dostępu, sprostowania, usunięcia lub ograniczenia przetwarzania danych. Możesz wycofać zgodę na przetwarzanie, zgłosić sprzeciw oraz skorzystać z innych praw wymienionych szczegółowo w polityce prywatności.

Jakie są podstawy prawne przetwarzania Twoich danych?

Podstawą prawną przetwarzania Twoich danych w celu świadczenia usług jest niezbędność do wykonania umów o ich świadczenie (tymi umowami są zazwyczaj regulaminy). Podstawą prawną przetwarzania danych w celu pomiarów statystycznych i marketingu własnego administratorów jest tzw. uzasadniony interes administratora. Przetwarzanie Twoich danych w celach marketingowych realizowanych przez Wirtualną Polskę na zlecenie Zaufanych Partnerów i bezpośrednio przez Zaufanych Partnerów będzie odbywać się na podstawie Twojej dobrowolnej zgody.