El glob
primero crea todas las expansiones posibles de nombre de archivo, por lo que primero generará la lista completa del patrón / globo de estilo shell que se le da. Solo entonces iterará sobre él, si se usa en contexto escalar. Por eso es tan difícil (¿imposible?) Escapar del iterador sin agotarlo; ver este post .
En su primer ejemplo, son 26 5 cadenas ( 11_881_376
), cada cinco caracteres de largo. Entonces, una lista de ~ 12 millones de cadenas, con un total (ingenuo) superior a 56Mb ... más la sobrecarga para un escalar, que creo que como mínimo es de 12 bytes o más. Entonces, en el orden de 100Mb, como mínimo, justo allí en una lista. †
No conozco ningún límite formal sobre la longitud de las cosas en Perl (que no sea en expresiones regulares), pero glob
¿todo eso internamente y debe haber límites indocumentados, tal vez algunos búferes se desbordan internamente? Es un poco excesivo.
En cuanto a una forma de evitar esto, genere esa lista de cadenas de 5 caracteres de forma iterativa, en lugar de dejar que glob
su magia entre bastidores. Entonces absolutamente no debería tener un problema.
Sin embargo, encuentro todo un poco grande para la comodidad, incluso en ese caso. Realmente recomendaría escribir un algoritmo que genere y proporcione un elemento de lista a la vez (un "iterador"), y trabaje con eso.
Hay buenas bibliotecas que pueden hacer eso (y muchas más), algunas de las cuales son Algorithm :: Loops recomendadas en una publicación anterior sobre este asunto (y en un comentario), Algorithm :: Combinatorics (mismo comentario), Set::CrossProduct
de otra respuesta aquí ...
También tenga en cuenta que, si bien este es un uso inteligente de glob
, la biblioteca está diseñada para trabajar con archivos. Además de mal uso en principio, ¡creo que verificará cada uno de los (los ~ 12 millones) nombres para una entrada válida ! (Consulte esta página ). Eso es mucho trabajo de disco innecesario. (Y si tuviera que usar "globos" como *
o ?
en algunos sistemas, devuelve una lista con solo cadenas que realmente tienen archivos, por lo que silenciosamente obtendría resultados diferentes).
† Obtengo 56 bytes para un tamaño de escalar de 5 caracteres. Si bien eso es para una variable declarada, que puede tomar un poco más que un escalar anónimo, en el programa de prueba con cadenas de longitud 4, el tamaño total real es de hecho un orden de magnitud mayor que el calculado ingenuamente. Entonces, lo real puede ser del orden de 1 Gb, en una sola operación.
Actualización Un programa de prueba simple que genera esa lista de cadenas largas de 5 caracteres (con el mismo glob
enfoque) se ejecutó durante 15 minutos en una máquina de clase servidor y tomó 725 Mb de memoria.
Produjo el número correcto de cadenas largas reales de 5 caracteres, aparentemente correcta, en este servidor.