glob
Najpierw tworzy wszystkie możliwe rozszerzenia nazw plików, więc będzie najpierw wygenerować pełną listę z powłoki stylu glob / wzór jest dany. Tylko wtedy będzie iterować, jeśli zostanie użyte w kontekście skalarnym. Dlatego tak trudno (nie?) Uciec z iteratora bez jego wyczerpania; zobacz ten post .
W pierwszym przykładzie jest to 26 5 ciągów znaków ( 11_881_376
), każdy o długości pięciu znaków. Więc lista ~ 12 milionów łańcuchów, z (naiwnym) sumą przekraczającą 56 Mb ... plus koszty ogólne dla skalara, który moim zdaniem wynosi co najmniej 12 bajtów. Tak więc, co najmniej 100 Mb, przynajmniej na jednej liście. †
Nie znam żadnych formalnych ograniczeń długości rzeczy w Perlu (innych niż regex), ale glob
czy to wszystko wewnętrznie i muszą istnieć nieudokumentowane ograniczenia - być może niektóre bufory są gdzieś przekroczone, wewnętrznie? To trochę przesada.
Jeśli chodzi o obejście tego - wygeneruj iteracyjnie tę listę ciągów 5-znakowych, zamiast pozwolić glob
rzucać swoją magią za kulisy. To absolutnie nie powinno mieć problemu.
Jednak uważam, że to wszystko jest nieco duże dla wygody, nawet w tym przypadku. Naprawdę polecam napisać algorytm, który generuje i udostępnia jeden element listy na raz („iterator”), i pracuję z tym.
Istnieją dobre biblioteki, które potrafią to zrobić (i wiele więcej), z których niektóre to Algorytm :: Pętle zalecane w poprzednim poście na ten temat (i w komentarzu), Algorytm :: Kombinatoryka (ten sam komentarz), Set::CrossProduct
z innej odpowiedzi tutaj ...
Zauważ też, że chociaż jest to sprytne zastosowanie glob
, biblioteka jest przeznaczona do pracy z plikami. Oprócz nadużycia w zasadzie myślę, że sprawdzi każde z (~ 12 milionów) nazw pod kątem prawidłowego wpisu ! (Zobacz tę stronę .) To dużo niepotrzebnej pracy na dysku. (A jeśli użyjesz „globów”, takich jak *
lub ?
w niektórych systemach, zwraca listę zawierającą tylko ciągi znaków, które faktycznie mają pliki, więc po cichu uzyskasz inne wyniki.)
† Dostaję 56 bajtów dla rozmiaru 5-znakowego skalara. Chociaż dotyczy to deklarowanej zmiennej, która może zająć nieco więcej niż anonimowy skalar, w programie testowym z łańcuchami o długości 4 rzeczywisty całkowity rozmiar jest rzeczywiście o rząd wielkości większy niż naiwnie obliczony. Tak więc rzeczywiste może być rzędu 1 Gb w jednej operacji.
Aktualizacja Prosty program testowy, który generuje tę listę łańcuchów o długości 5 znaków (stosując to samo glob
podejście), działał przez 15 minut na komputerze klasy serwerowej i zajął 725 Mb pamięci.
Na tym serwerze wytworzono odpowiednią liczbę rzeczywistych łańcuchów o długości 5 znaków, pozornie poprawnych.