O glob
primeiro cria todas as expansões possíveis de nomes de arquivos, para gerar primeiro a lista completa a partir do padrão / glob no estilo de shell que é fornecido. Somente então ele irá iterar sobre ele, se usado em contexto escalar. É por isso que é tão difícil (impossível?) Escapar do iterador sem esgotá-lo; veja este post .
No seu primeiro exemplo, são 26 5 strings ( 11_881_376
), cada uma com cinco caracteres. Portanto, uma lista de ~ 12 milhões de strings, com um total (ingênuo) superior a 56Mb ... mais a sobrecarga de um escalar, que eu acho que é no mínimo 12 bytes ou mais. Então, na ordem dos 100Mb, no mínimo, ali mesmo em uma lista. †
Eu não estou ciente de quaisquer limites formais no tamanho das coisas no Perl (exceto no regex), mas glob
tudo isso internamente e deve haver limites não documentados - talvez alguns buffers sejam invadidos em algum lugar, internamente? É um pouco excessivo.
Como uma maneira de contornar isso - gere a lista de sequências de 5 caracteres de forma iterativa, em vez de deixar glob
rolar sua mágica nos bastidores. Então absolutamente não deve ter um problema.
No entanto, acho a coisa toda um pouco grande para o conforto, mesmo nesse caso. Eu realmente recomendo escrever um algoritmo que gere e forneça um elemento de lista por vez (um "iterador") e trabalhe com isso.
Existem boas bibliotecas que podem fazer isso (e muito mais), algumas das quais são Algorithm :: Loops recomendados em um post anterior sobre esse assunto (e em um comentário), Algorithm :: Combinatorics (mesmo comentário), Set::CrossProduct
de outra resposta aqui ...
Observe também que, embora este seja um uso inteligente glob
, a biblioteca deve funcionar com arquivos. Além de usá-lo mal em princípio, acho que ele verificará cada um dos (12 milhões) nomes para uma entrada válida ! (Veja esta página .) É muito trabalho em disco desnecessário. (E se você fosse usar "bolhas" como *
ou ?
em alguns sistemas ele retorna uma lista com apenas cordas que realmente têm arquivos, assim você iria tranquilamente obter resultados diferentes.)
† Estou recebendo 56 bytes para o tamanho de um escalar de 5 caracteres. Enquanto isso é para uma variável declarada, que pode demorar um pouco mais do que um escalar anônimo, no programa de teste com seqüências de comprimento 4, o tamanho total real é de fato uma boa ordem de magnitude maior que a calculada ingenuamente. Portanto, a coisa real pode muito bem estar na ordem de 1 GB, em uma operação.
Atualização Um programa de teste simples que gera essa lista de sequências longas de 5 caracteres (usando a mesma glob
abordagem) foi executado por 15 minutos em uma máquina de classe de servidor e consumiu 725 Mb de memória.
Ele produziu o número certo de strings reais de 5 caracteres, aparentemente corretas, neste servidor.