Rozumiem, że lista faktycznie zawiera wartości, a sekwencja jest aliasem IEnumerable<T>
. Kiedy w praktycznym programowaniu F # powinienem używać sekwencji, a nie listy?
Oto kilka powodów, dla których widzę, że sekwencja byłaby lepsza:
- Podczas interakcji z innymi językami lub bibliotekami .NET, które wymagają
IEnumerable<T>
. - Trzeba przedstawić nieskończoną sekwencję (prawdopodobnie niezbyt przydatne w praktyce).
- Potrzebujesz leniwej oceny.
Czy są jeszcze inni?
seq
wygenerowany w ten sposób wygeneruje różne liczby losowe za każdym razem, gdy na to spojrzysz. To oczywiście może być źródłem niedeterministycznych błędów ...Odpowiedzi:
Myślę, że podsumowanie, kiedy wybrać,
Seq
jest całkiem dobre. Oto kilka dodatkowych punktów:Seq
domyślnie podczas pisania funkcji, ponieważ wtedy działają one z dowolną kolekcją .NETSeq
jeśli potrzebujesz zaawansowanych funkcji, takich jakSeq.windowed
lubSeq.pairwise
Myślę, że wybór
Seq
domyślny jest najlepszą opcją, więc kiedy powinienem wybrać inny typ?Użyj,
List
gdy potrzebujesz przetwarzania rekurencyjnego przy użyciuhead::tail
wzorców(aby zaimplementować niektóre funkcje, które nie są dostępne w standardowej bibliotece)
Użyj,
List
gdy potrzebujesz prostej, niezmiennej struktury danych, którą możesz zbudować krok po kroku(na przykład, jeśli chcesz przetworzyć listę w jednym wątku - aby wyświetlić statystyki - i jednocześnie kontynuować budowanie listy w innym wątku w miarę otrzymywania więcej wartości, np. z usługi sieciowej)
Używaj
List
podczas pracy z krótkimi listami - lista jest najlepszą strukturą danych do użycia, jeśli wartość często reprezentuje pustą listę , ponieważ jest bardzo wydajna w tym scenariuszuUżyj,
Array
gdy potrzebujesz dużych kolekcji typów wartości(tablice przechowują dane w płaskim bloku pamięci, więc w tym przypadku są bardziej wydajne w pamięci)
Użyj,
Array
gdy potrzebujesz dostępu swobodnego lub większej wydajności (i lokalizacji pamięci podręcznej)źródło
List
[...], gdy potrzebujesz prostej, niezmiennej struktury danych , którą możesz zbudować krok po kroku [...] i jednocześnie kontynuować budowanie listy w innym wątku [...]” Czy możesz rozwinąć swoją znaczenie tutaj / jak to działa? Dzięki.x::xs
bez przerywania istniejących pracowników, którzy mogą być w trakcie iteracjixs
Również preferuj,
seq
gdy:Nie chcesz jednocześnie przechowywać w pamięci wszystkich elementów.
Wydajność nie jest ważna.
Musisz coś zrobić przed i po wyliczeniu, np. Połączyć się z bazą danych i zamknąć połączenie.
Nie łączysz się (powtórzone
Seq.append
przepełnienie stosu).Preferuj
list
kiedy:Jest kilka elementów.
Będziesz dużo udawać i dekapitować.
Ani
seq
nielist
są dobre dla paralelizmu, ale to niekoniecznie oznacza, że są one również złe. Na przykład, możesz użyć albo do przedstawienia małej grupy oddzielnych zadań do wykonania równolegle.źródło
Tylko jeden mały punkt:
Seq
iArray
są lepsze niż wList
przypadku równoległości.Masz kilka opcji: PSeq z F # PowerPack, Array.Parallel modułu i Async.Parallel (asynchroniczny obliczeń). Lista jest okropna do równoległego wykonywania ze względu na jej sekwencyjny charakter (
head::tail
skład).źródło
Array
lubPSeq
jest znacznie lepsze.seq
jest to lepsze niż wlist
przypadku równoległości?seq
są również okropne do równoległego wykonywania ze względu na ich sekwencyjną naturę ...lista jest bardziej funkcjonalna, przyjazna matematyce. gdy każdy element jest równy, 2 listy są równe.
sekwencja nie jest.
let list1 = [1..3] let list2 = [1..3] printfn "equal lists? %b" (list1=list2) let seq1 = seq {1..3} let seq2 = seq {1..3} printfn "equal seqs? %b" (seq1=seq2)
źródło
Zawsze powinieneś ujawniać
Seq
w swoich publicznych interfejsach API. UżyjList
iArray
w swoich wewnętrznych wdrożeniach.źródło
Seq
jest postrzegane jakoIEnumerable<T>
?seq
są tak złe dla paralelizmu.