Fakt, że domyślna implementacja Haskella String
nie jest wydajna, zarówno pod względem szybkości, jak i pamięci, jest dobrze znana. O ile mi wiadomo, na ogół w Haskell są stosowane jako listy pojedynczo powiązane, a dla większości małych/prostych typów danych (np. Int
) nie wydaje się to dobrym pomysłem, ale dla String
wydaje się, że to całkowita przesada. Niektóre z opinii na ten temat to:Dlaczego domyślna implementacja łańcucha Haskella jest połączoną listą znaków?
na prostych wskaźników, takich jak to, a nawet programów napisanych w językach interpretowanych, takich jak Python może przewyższyć kod Haskell, który używa String o rząd wielkości.
Efficient String Implementation in Haskell
Ponieważ ciąg jest po prostu [Char], który jest powiązany lista Char, to znaczy Struny mają słabą lokalizację odniesienia i znów oznacza, że Struny są dość duże w pamięci, co najmniej jest to N * (21 bitów + megabitów), gdzie N jest długością łańcucha, a M jest wielkością wskaźnika (...). Struny są znacznie mniej podatne na zoptymalizowanie do pętli itp. Przez kompilator.
wiem, że Haskell ma ByteString
s (i Array
e) w kilku przyjemnych smakach i że mogą wykonać zadanie ładnie, ale spodziewałbym domyślna implementacja jest najbardziej wydajny jeden.
TL; DR: Dlaczego domyślna implementacja Haskella String
jest listą pojedynczo połączoną, mimo że jest bardzo nieefektywna i rzadko używana w aplikacjach świata rzeczywistego (z wyjątkiem tych naprawdę prostych)? Czy są jakieś historyczne powody? Czy łatwiej jest wdrożyć?
Zakładam, że to dlatego, że '[Char]' jest okropnie wygodne. –
Czuję, że warto wspomnieć, że 'ByteString' zdecydowanie nie jest tekstem, a' Array' nie jest dużo lepszym - 'Text' jest naprawdę dobrym rozwiązaniem. –
Haskell/= GHC. Posiadanie reprezentacji ciągów "żółtych przez cały czas" było godnym pochwały projektem na początku czasów Haskella, kiedy było kilka różnych kompilatorów/interpretatorów. –