Wielokrotnie pisałem o różnych metodach definiowania sekcji krytycznej w kodzie. Do dyspozycji mamy spinning, który nie usypia wątku. Tak naprawdę dla systemu Windows, taki wątek wciąż istnieje i wykonuje pracę – innymi słowy marnuje czas CPU. Jeśli chcemy zatrzymać wątek na krótko wtedy jest to bardzo wydajne ponieważ nie musimy zmieniać kontekstu (BARDZO kosztowne), korzystać z funkcji Windows (spinning to czysta metoda .NET) czy planować (scheduling) następnych wątków. Jeśli mechanizmy takie jak spin...
Strona głównaUżytkownik
pzielinski | użytkownik
Sztuka programowania 4291 dni, 15 godzin, 46 minut temu 80 źrodło rozwiń
Operacje na plikach mogą być bardzo czasochłonne. Z tego względu, dobrym zwyczajem jest umieszczenie kodu w osobnym wątku. Często popełnianym błędem jest samodzielne tworzenie wątku:internalstaticclass Sample { publicstaticvoid Main() { var reader =new FileStream(@"c:\setup\1.txt", FileMode.Open); Task.Factory.StartNew(()=>ReadAsync(reader)); } privatestaticvoid ReadAsync(Stream reader) { byte[]buffer=newbyte[100]; reader.Read(buffer, 0, 100); reader.Clos...
Sztuka programowania 4294 dni, 13 godzin, 33 minuty temu 162 źrodło rozwiń
Kolejna część cyklu – zapraszam do lektury: http://msdn.microsoft.com/pl-pl/library/optymalizacja-kodu-c-sharp–czesc-3
Sztuka programowania 4297 dni, 14 godzin, 41 minut temu 215 źrodło rozwiń
W celu optymalizacji każdy procesor posiada swój cache. Temat jest dosyć rozbudowany bo zwykłe cache jest podzielony na kilka warstw aby przyśpieszyć dostęp do niego. W dzisiejszym w poście chciałbym wprowadzić pojęcie cache line co jest tak naprawdę po prostu wpisem w pamięci podręcznej. Jeśli procesor czyta jakieś dane to umieszcza je w cache line. Cache line to nie tylko jedna, pojedyncza zmienna a na przykład 64 bajty. Jeśli zatem czytamy pojedynczą zmienną Int32, w rzeczywistości procesor przeczyta...
Sztuka programowania 4300 dni, 23 godziny, 47 minut temu 196 źrodło rozwiń
Czasami zachodzi potrzeba serializacji obiektów, które powinny mieć maksymalnie jedną kopie w tym samym AppDomain. Klasycznym przykładem jest System.DBNull, którego deklaracja wygląda następująco:[SerializableAttribute] [ComVisibleAttribute(true)] publicsealedclass DBNull : ISerializable, IConvertible Załóżmy, że mamy klasę, w której jedna z właściwości ma wartość System.DBNull. Oczywiście podczas serializacji i potem deserializacji nie chcemy tworzyć nowej instancji DBNull – jest to sprzeczne z ...
Sztuka programowania 4303 dni, 23 godziny, 10 minut temu 106 źrodło rozwiń
Załóżmy, że mamy następujący kod:[Serializable] class Person { publicstring Name { get; set; } } Atrybut Serializable mówi, że będzie wspierana serializacja za pomocą IFormatter (np. BinaryFormatter). Jeśli chcemy wspierać ten mechanizm, zawsze powinniśmy tworzyć jawnie backing-field. Kompilator w końcu może wygenerować tak naprawdę dowolną nazwę. Zajrzyjmy do Reflector, aby zobaczyć jak wygląda wewnętrzna struktura: Wygenerowane pole to:[CompilerGenerated] privatestring
Sztuka programowania 4306 dni, 12 godzin, 14 minut temu 147 źrodło rozwiń
W celu wykonania jakiegoś kodu za pomocą refleksji, należy najpierw zebrać informację o danym polu. Załóżmy, że mamy następującą klasę:class Sample { publicvoid PrintSomething() { Console.WriteLine("Something"); } } W celu wykonania metody za pomocą refleksji można:object sample =new Sample(); MethodInfo info=sample.GetType().GetMethod("PrintSomething"); info.Invoke(sample, null); Generalnie obiekty takie jak MemberInfo czy MethodInfo pożerają mnóstwo pamięci – są one dość ciężk...
Sztuka programowania 4308 dni, 15 godzin, 7 minut temu 127 źrodło rozwiń
GC nic nie wie o zasobach niezarządzanych. Nie wie ile pamięci one zajmują oraz oczywiście nie jest w stanie zwolnić takich zasobów. O zarządzaniu taką pamięcią pisałem już wiele razy. Opisywałem również zasadę działania GC. Zwykle jest on odpalany po przekroczeniu pewnego progu zużycia pamięci. Niestety, jak wspomniałem, GC nie wie nic o niezarządzanych zasobach. Co w przypadku gdy wrapper zużywa bardzo mało pamięci a zasoby niezarządzane w nim konsumują bardzo wiele pamięci? Dzięki metodom AddMemoryPre...
Sztuka programowania 4312 dni, 12 godzin, 26 minut temu 139 źrodło rozwiń
Czasami zachodzi potrzeba wykonania krytycznego kodu, który zużywa dużo zasobów. Podobnie jak w CER, nie chcemy wykonywać kodu jeśli wiemy, że nie ma wystarczającej pamięci. W .NET istnieje klasa MemoryFailPoint, która potrafi z góry “zaalokować” określoną pamięć.publicsealedclass MemoryFailPoint : CriticalFinalizerObject, IDisposable { public MemoryFailPoint(Int32 sizeInMegabytes); ~MemoryFailPoint(); publicvoid Dispose(); } MemoryFailPoint sprawdzi czy jest dostępna pamięć. Jeśli jej nie...
Sztuka programowania 4317 dni, 6 godzin, 25 minut temu 103 źrodło rozwiń
W ostatnim poście pisałem jak prawidłowo wykonać finalizację obiektu jeśli mowa o zasobach niezarządzanych, których zwolnienie jest krytyczne. Dzisiaj o obiekcie, który jest bardzo często wykorzystywany w sytuacjach gdzie należy przechowywać wskaźnik do zasobów niezarządzanych. Zacznijmy od jego definicji:[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, UnmanagedCode =true)] publicabstractclass SafeHandle : CriticalFinalizerObject, IDisposable Co to oznacza? Wszystkie rzeczy jakie daje n...
Sztuka programowania 4323 dni, 12 godzin, 23 minuty temu 105 źrodło rozwiń
Funkcja Array.Sort sortuje tablicę elementów. Niestety algorytm jest niestabilny co nie zawsze jest dobrym rozwiązaniem. Rozważmy poniższy kod:publicclass Person { publicint Age { get; set; } publicstring Name { get; set; } } internalclass Program { publicstaticvoid Main() { var persons =new[] { new Person { Age =1, Name ="a" }, new Person { Age =2, Name ="b" }, new Person { Age =3, Name ="c" }, new Person { Age =2, Name ="e" }, new Person { Age =1,...
Sztuka programowania 4323 dni, 23 godziny, 29 minut temu 136 źrodło rozwiń
O destruktorach pisałem już kilka razy na blogu. W wielkim skrócie – zawsze należy przemyśleć decyzje o implementacji Finalize ponieważ wiąże to się z spadkiem wydajności (obiekt może być nawet “wypromowany” do drugiej generacji GC). Czasami jednak zachodzi taka potrzeba – głównie w przypadku użycia niezarządzanych zasobów. CriticalFinalizerObject daje nam jeszcze kilka dodatkowych gwarancji. Przed przeczytaniem tego wpisu, polecam zapoznanie się z poprzednim postem o CER. Co zatem da nam dziedziczenie ...
Sztuka programowania 4325 dni, 23 godziny, 16 minut temu 82 źrodło rozwiń
Kolejna cześć artykułu o wydajności w C#. Zapraszam do lektury!
Sztuka programowania 4326 dni, 21 godzin, 24 minuty temu 203 źrodło rozwiń
Z pewnością każdy z Was odpowiedziałby, że pisze solidny kod. Oczywiście zależy to od przyjętych metryk i definicji “solidny kod”. Nie zawsze warto skupiać uwagę na drobiazgach i pułapach, których jest na prawdę wiele. Czasami jednak jest to konieczność, głównie w aplikacjach serwerowych, które muszą działać, nawet, gdy dostarczone dane są np. nieprawidłowe. W przypadku awarii, niedopuszczalne jest wtedy zepsucie stanu aplikacji. Rozważmy, taką sytuację:try { // jakaś logika} catch(IOException e) { ...
Sztuka programowania 4331 dni, 18 godzin, 35 minut temu 185 źrodło rozwiń
Zadanie jest następujące. Mamy w pliku tekstowym dane zawierające m.in datę z góry w zdefiniowanym formacie a mianowicie 2012/10/05 (piąty październik 2012). Dla uproszczenia, ograniczymy się tylko do dnia, miesiąca i roku, bez czasu. Pierwsze podejście, najgorsze mogłoby wyglądać następująco:string timestamp =""; DateTime dateTime = DateTime.Parse(timestamp); Console.WriteLine(dateTime); Dlaczego jest to niepoprawne? W niektórych ustawieniach regionalnych (np. USA) format jest następujący “yyyy/dd/M...
Sztuka programowania 4332 dni, 18 godzin, 5 minut temu 196 źrodło rozwiń
Rozpocząłem pisanie nowego cyklu artykułów, tym razem o wydajności w C#. Pierwsza część właśnie została opublikowana i zawiera przede wszystkim wprowadzenie do tematu oraz kilka konkretnych przykładów. Kolejne części już wkrótce i będą prezentowały poszczególne konstrukcje w C#. Na blogu już pisałem niejednokrotnie o wydajności w C#, ale artykuł oprócz tego co już tutaj zostało napisane, zawiera dodatkowe informacje i przykłady. Dla tych co nie czytali blog’a myślę, że taki cykl stanowi po prostu kompend...
Sztuka programowania 4336 dni, 11 godzin, 37 minut temu 335 źrodło rozwiń
Opisywałem już mechanizm konwersji zdarzeń .NET do IObservable. W RX istnieje dodatkowo nowy mechanizm, mający na celu zastąpić standardowe zdarzenia .NET – przynajmniej w części przypadków. Zastanówmy się, co jest złego tak naprawdę w obsłudze zdarzeń w .NET? 1. Dość często programiści zapominają usunąć zdarzenie co może skutkować memory leak. Czasami jest ciężko zdefiniować moment, w którym należy usunąć zdarzenie. Pewnym rozwiązaniem problemu może być zastosowanie wzorca weak event pattern ale jak w...
Sztuka programowania 4342 dni, 22 godziny, 7 minut temu 41 źrodło rozwiń
Kilka postów wcześniej, pokazałem jak narysować linię za pomocą RX oraz przechwytywania zdarzeń. Dla przypomnienia udało nam się narysować prostą linie z punktu (0,0) do aktualnej pozycji kursora:publicclass MyCanvas : Canvas { private Point _endPoint; public MyCanvas() { var eventsSource = Observable.FromEventPattern
Sztuka programowania 4342 dni, 22 godziny, 7 minut temu 31 źrodło rozwiń
W dzisiejszym wpisie znów wracamy do tematu RX. Postaram się wyjaśnić jak można ze sobą połączyć kilka IObservable. W RX istnieje naprawdę wiele metod umożliwiających wykonanie tego i na początku może wydawać się to dość skomplikowane, ze względu na liczbę sposobów w jaki można to wykonać. 1. Observable.Amb – zawsze zwraca wyłącznie tą sekwencje, która została jako pierwsza wygenerowana. Jeśli zatem mamy MouseMove i MouseUp wtedy zostanie zwrócone te zdarzenie, które jako pierwsze miało miejsce. Przykł...
Sztuka programowania 4344 dni, 21 godzin, 53 minuty temu 38 źrodło rozwiń
Co wyświetli poniższy fragment kodu?internalclass Program { publicstaticvoid Main() { var timer =new Timer(TimerCallback, null, 0, 1000); Console.ReadLine(); } privatestaticvoid TimerCallback(Object o) { Console.WriteLine("Callback: "+ DateTime.Now); } } Powyższy konstruktor uruchamia timer i spodziewalibyśmy się, że na ekranie po prostu będą wyświetlane kolejne callbacki. W praktyce jednak dokonywana jest pewna optymalizacja, która ma fatalne efekty. Można zauwa...
Sztuka programowania 4347 dni, 10 godzin, 55 minut temu 102 źrodło rozwiń