Mimo że możesz użyć drugiego wątku do analizy danych po ich przeczytaniu, prawdopodobnie nie uzyskasz w ten sposób ogromnej ilości danych. Próba użycia więcej niż jednego wątku do odczytania danych prawie na pewno wpłynie na szybkość, a nie na jego poprawę. Używanie wielu wątków do przetwarzania danych nie ma sensu - przetwarzanie będzie wiele razy szybsze niż czytanie, więc nawet z jednym dodatkowym wątkiem, limitem będzie prędkość dysku.
Jednym (możliwym) sposobem na uzyskanie znacznej prędkości jest ominięcie zwykłych iostreamów - podczas gdy niektóre są prawie tak szybkie, jak przy użyciu C FILE *, nic nie wiem o wiele szybciej, a niektóre są znacznie wolniej. Jeśli używasz tego w systemie (np. Windows), który ma model I/O, który wyraźnie różni się od C, możesz uzyskać znacznie więcej przy odrobinie staranności.
Problem jest dość prosty: plik, który czytasz jest (potencjalnie) większy niż przestrzeń pamięci podręcznej, którą masz dostęp - ale nic nie zyskasz dzięki buforowaniu, ponieważ nie będziesz ponownie czytać fragmentów plik ponownie (przynajmniej jeśli robisz to rozsądnie). W związku z tym chcesz powiedzieć systemowi, aby pominął buforowanie i po prostu przesyłaj dane tak bezpośrednio, jak to możliwe, z dysku twardego do pamięci, gdzie możesz je przetworzyć. W systemie uniksopodobnym, to prawdopodobnie open()
i read()
(i nie przyniesie Ci to dużo). W systemie Windows to CreateFile
i ReadFile
, przekazując flagę FILE_FLAG_NO_BUFFERING
do CreateFile
- i prawdopodobnie zwiększy się dwukrotnie twoja prędkość, jeśli zrobisz to dobrze.
Dostałeś również kilka odpowiedzi zalecających przetwarzanie przy użyciu różnych konstrukcji równoległych. Myślę, że są one zasadniczo błędne. O ile nie zrobisz czegoś okropnie głupiego, czas policzenia słów w pliku będzie o kilka milisekund dłuższy niż po prostu odczytanie pliku.
Strukturę, której użyłbym, miałaby dwa bufory, powiedzmy, po jednym megabajcie. Odczytaj dane do jednego bufora. Odwróć ten bufor do wątku zliczającego, aby policzyć słowa w tym buforze. W tym czasie odczytaj dane do drugiego bufora. Gdy już to zrobisz, po prostu zamień bufory i kontynuuj. Jest trochę dodatkowego przetwarzania, które musisz wykonać, wymieniając bufory, aby poradzić sobie ze słowem, które może przekroczyć granicę z jednego bufora do drugiego, ale jest to dość trywialne (w zasadzie, jeśli bufor nie kończy się na kolorze białym spacja, wciąż jesteś słowem, gdy zaczniesz operować na następnym buforze danych).
Dopóki jesteś pewny, że będzie używany tylko na maszynie wieloprocesorowej (wielordzeniowej), używanie prawdziwych wątków jest w porządku. Jeśli jest szansa, że kiedykolwiek zostanie to zrobione na maszynie jednordzeniowej, lepiej od razu użyć jednego wątku z nakładającymi się we/wy.
Czy możesz dokładniej określić, w jaki sposób będzie wyszukiwany plik tekstowy? Czy plik jest względnie statyczny i musisz uruchomić wiele wyszukiwań w pliku statycznym? Czy będziesz musiał wyszukiwać wiele różnych słów, czy nie jest tak ważne, aby wyszukiwanie pojedynczego słowa zakończyło się tak szybko, jak to możliwe? Czy w poszukiwanych słowach zazwyczaj pojawia się wzorzec - I.E. kilka słów składa się na większość twoich wyszukiwań. – jthg
Użytkownik chce uniknąć ładowania go w pamięci naraz, strumienie zostały utworzone dla danej sytuacji. –
Jaki jest cel używania wątków do czytania różnych części pliku? Zakładając, że twój plik znajduje się na konwencjonalnym dysku twardym, najszybszym sposobem jest przesyłanie strumieniowe bezpośrednio do pliku. Jeśli masz wiele wątków z prośbą o wiele części pliku w tym samym czasie, głowa twojego dysku będzie przeskakiwać w każdym miejscu, co zrównoważy wszelkie korzyści, jakie możesz uzyskać dzięki wielowątkowości. – StriplingWarrior