Kiedyś przejrzałem funkcje bibliotek tablicowych Haskell, które są dla mnie ważne, i skompilowałem tabelę porównawczą (tylko arkusz kalkulacyjny: bezpośredni link ). Więc spróbuję odpowiedzieć.
Na jakiej podstawie mam wybierać między Vector.Unboxed a UArray? Obie są tablicami rozpakowanymi, ale abstrakcja Vector wydaje się mocno reklamowana, szczególnie wokół fuzji pętli. Czy Vector jest zawsze lepszy? Jeśli nie, kiedy należy użyć której reprezentacji?
UArray może być preferowany względem Vector, jeśli potrzebne są tablice dwuwymiarowe lub wielowymiarowe. Ale Vector ma lepszy interfejs API do manipulowania, no cóż, wektorami. Ogólnie rzecz biorąc, Vector nie nadaje się dobrze do symulowania tablic wielowymiarowych.
Vector.Unboxed nie może być używany ze strategiami równoległymi. Podejrzewam, że UArray również nie może być używany, ale przynajmniej bardzo łatwo jest przejść z UArray na boxed Array i zobaczyć, czy korzyści z równoległości przewyższają koszty pakowania.
W przypadku obrazów kolorowych będę chciał przechowywać trójek 16-bitowych liczb całkowitych lub trójek liczb zmiennoprzecinkowych o pojedynczej precyzji. Czy w tym celu łatwiej jest używać Vector lub UArray? Bardziej wydajne?
Próbowałem używać tablic do reprezentowania obrazów (chociaż potrzebowałem tylko obrazów w skali szarości). Do obrazów kolorowych użyłem biblioteki Codec-Image-DevIL do odczytu / zapisu obrazów (powiązania z biblioteką DevIL), dla obrazów w skali szarości użyłem biblioteki pgm (czysty Haskell).
Moim głównym problemem związanym z Arrayem było to, że zapewnia on tylko pamięć o dostępie swobodnym, ale nie zapewnia wielu sposobów budowania algorytmów Array ani nie zawiera gotowych do użycia bibliotek procedur tablicowych (nie współpracuje z bibliotekami algebry liniowej, nie nie pozwalają na wyrażanie splotów, fft i innych przekształceń).
Prawie za każdym razem, gdy trzeba zbudować nową tablicę z istniejącej, należy skonstruować pośrednią listę wartości (jak w mnożeniu macierzy z Łagodnego wprowadzenia). Koszt budowy tablicy często przewyższa korzyści płynące z szybszego losowego dostępu do tego stopnia, że reprezentacja oparta na liście jest szybsza w niektórych moich przypadkach użycia.
STUArray mógł mi pomóc, ale nie lubiłem walczyć z tajemniczymi błędami typu i wysiłkami niezbędnymi do napisania kodu polimorficznego za pomocą STUArray .
Problem z tablicami polega na tym, że nie nadają się one dobrze do obliczeń numerycznych. Hmatrix 'Data.Packed.Vector i Data.Packed.Matrix są lepsze pod tym względem, ponieważ są dostarczane wraz z solidną biblioteką macierzy (uwaga: licencja GPL). Pod względem wydajności, przy mnożeniu macierzy, hmatrix była wystarczająco szybka ( tylko nieznacznie wolniejsza niż Octave ), ale bardzo wymagała pamięci (zużywała kilka razy więcej niż Python / SciPy).
Istnieje również biblioteka blas dla macierzy, ale nie jest oparta na GHC7.
Nie miałem jeszcze dużego doświadczenia z Repą i nie rozumiem dobrze kodu repa. Z tego co widzę ma bardzo ograniczony zakres gotowych do użycia algorytmów macierzowych i tablicowych napisanych na wierzchu, ale przynajmniej da się wyrazić za pomocą biblioteki ważne algorytmy. Na przykład, istnieją już procedury mnożenia macierzy i splotu w algorytmach repa. Niestety wydaje się, że splot jest teraz ograniczony do jądra 7 × 7 (dla mnie to nie wystarcza, ale powinno wystarczyć do wielu zastosowań).
Nie próbowałem powiązań Haskell OpenCV. Powinny być szybkie, ponieważ OpenCV jest naprawdę szybkie, ale nie jestem pewien, czy wiązania są kompletne i wystarczająco dobre, aby nadawały się do użytku. Ponadto OpenCV ze swej natury jest bardzo niezbędny, pełen destrukcyjnych aktualizacji. Podejrzewam, że ciężko jest zaprojektować na dodatek ładny i wydajny funkcjonalny interfejs. Jeśli ktoś pójdzie drogą OpenCV, prawdopodobnie użyje reprezentacji obrazu OpenCV wszędzie i użyje procedur OpenCV do manipulowania nimi.
W przypadku obrazów bitonalnych będę musiał przechowywać tylko 1 bit na piksel. Czy istnieje predefiniowany typ danych, który może mi pomóc, pakując wiele pikseli w słowo, czy też jestem sam?
O ile wiem, Unboxed tablice Bools zajmują się pakowaniem i rozpakowywaniem wektorów bitowych. Pamiętam, jak patrzyłem na implementację tablic Bools w innych bibliotekach i nie widziałem tego nigdzie indziej.
Wreszcie moje tablice są dwuwymiarowe. Przypuszczam, że mógłbym poradzić sobie z dodatkowym kierunkiem narzuconym przez reprezentację jako „tablica tablic” (lub wektor wektorów), ale wolałbym abstrakcję, która obsługuje mapowanie indeksów. Czy ktoś może polecić coś ze standardowej biblioteki lub z Hackage?
Oprócz Vector (i prostych list), wszystkie inne biblioteki tablic mogą reprezentować dwuwymiarowe tablice lub macierze. Przypuszczam, że unikają niepotrzebnego pośrednictwa.