2012-01-31 8 views
7

Mam zamiar przekonwertować aplikację C# na Haskell jako mój pierwszy "prawdziwy" projekt Haskella. Jednak chcę się upewnić, że jest to projekt, który ma sens. Aplikacja zbiera pakiety danych z ~ 15 strumieni szeregowych o częstotliwości około 1 kHz, ładuje te wartości do odpowiednich buforów kołowych w moim obiekcie "kontekstowym", każdy z ~ 25000 elementów, a następnie z częstotliwością 60 Hz wysyła te tablice do OpenGL dla wyświetlanie przebiegu. (W ten sposób ma być przechowywane jako tablica lub co najmniej konwertowane do tablicy co 16 ms). Na moim obiekcie kontekstowym znajduje się także około 70 pól, które utrzymuję tylko bieżącą (najnowszą) wartość, a nie przebieg strumienia.Czy możliwe jest tworzenie szybkich, dużych, okrągłych macierzy buforowych do nagrywania strumieniowego w Haskell?

Jest kilka aspektów tego projektu, które dobrze pasują do Haskella, ale martwię się tylko wydajnością. Jeśli dla każdego nowego punktu danych w dowolnym strumieniu, będę musiał sklonować cały obiekt kontekstu za pomocą 70 pól i 15 tablic z 25000 elementów, oczywiście wystąpią problemy z wydajnością.

Czy obejdę to, umieszczając wszystko w IO-Monadzie? Ale wtedy wydaje się, że w pewien sposób nie uda się użyć Haskella, prawda? Również cały mój kod w C# jest sterowany zdarzeniami; czy jest tam jakiś idiom w Haskell? Wygląda na to, że dodanie detektora tworzy "efekt uboczny" i nie jestem pewien, jak dokładnie by to zrobiono.

Odpowiedz

5

Tak, prawdopodobnie będziesz chciał użyć monopułę IO do modyfikowania danych. Nie sądzę, aby monada ST była odpowiednia dla tej przestrzeni problemowej, ponieważ aktualizacje danych są przeplatane rzeczywistymi operacjami IO (odczytywanie strumieni wejściowych). Ponieważ trzeba wykonać IO w ST przy użyciu unsafeIOToST, uważam, że lepiej jest używać IO bezpośrednio.Innym podejściem ze ST jest ciągłe rozmrażanie i zamrażanie tablicy; jest to nieporządne, ponieważ musisz zagwarantować, że stare kopie danych nigdy nie będą używane.

Chociaż evidence shows że czysty roztwór (w postaci Data.Sequence.Seq) jest często szybciej niż przy użyciu danych zmienny, biorąc pod uwagę swoje wymagania, które dane są wypychane do OpenGL, będziesz możliwe uzyskać lepszą wydajność pracy z tablicy bezpośrednio. Chciałbym użyć funkcji z Data.Vector.Storable.Mutable (z pakietu wektorowego), ponieważ wtedy masz dostęp do eksportu do ForeignPtr.

Możesz obejrzeć strzałki (Yampa), aby uzyskać bardzo popularne podejście do kodu sterowanego zdarzeniami. Kolejnym obszarem jest reaktywność funkcjonalna (FRP). W tej domenie zaczynają znajdować się dość dojrzałe biblioteki, takie jak Netwire lub reaktywny banan. Nie wiem, czy zapewniliby oni odpowiednią wydajność dla twoich wymagań; Używałem ich głównie do programowania typu gui.

7

Spójrz na ten link, pod sekcją „ST monady”:

http://book.realworldhaskell.org/read/advanced-library-design-building-a-bloom-filter.html

Powrót w sekcji „Modyfikowanie elementów tablicy”, wspomnieliśmy że modyfikując niezmienny układ jest niewspółmiernie drogie, ponieważ wymaga ono skopiowania całej tablicy. Użycie tablicy UArray nie zmienia tego faktu, więc co możemy zrobić, aby obniżyć koszty do znośnych poziomów?

W języku imperatywnym po prostu zmienilibyśmy elementy tablicy w miejscu; to też będzie nasze podejście w Haskell.

Haskell zapewnia specjalną monadę o nazwie ST, która pozwala nam bezpiecznie pracować z przy stanie zmiennym. W porównaniu z monadą państwową ma ona potężne dodatkowe możliwości.

Możemy rozmrozić niezmienną tablicę, aby uzyskać zmienną tablicę; zmodyfikuj zmienną tablicę ; i zamroź nową niezmienną tablicę, gdy wykonamy .

...

monady IO zapewnia również te możliwości. Główną różnicą między nimi jest to, że monada ST jest celowo zaprojektowana, abyśmy mogli uciec z niej z powrotem do czystego kodu Haskella.

Powinna istnieć możliwość modyfikacji w miejscu i nie pokona ona w końcu celu używania Haskella.

Powiązane problemy