Eu tenho um arquivo de texto com uma palavra em cada linha, o tamanho do arquivo é 800 GB. Eu preciso classificar as palavras em ordem alfabética.
Eu tentei usar o programa de classificação do Windows usando:
sort.exe input.txt /o output.txt
que fornece o erro: Não há memória principal suficiente para concluir a classificação.
Eu tenho 32 GB de RAM; portanto, quando tento especificar 10 GB de memória para o tipo usando:
sort.exe input.txt /o output.txt /M 10000000
Eu recebo:
Aviso: o tamanho da memória especificada está sendo reduzido para a memória de paginação disponível.
O registro de entrada excede o comprimento máximo. Especifique um máximo maior.
Quais são as minhas opções?
Respostas:
Quais são as minhas opções?
Tente o utilitário de classificação de linha de comando Freeware CMSort .
Ele usa vários arquivos temporários e os mescla no final.
Um usuário relata que classificou um arquivo de 130.000.000 bytes.
Se você deseja ajustar algum código por conta própria, também há Classificando arquivos de texto grandes - CodeProject - "Algoritmo de linhas de classificação em arquivos de texto cujo tamanho excede a memória disponível"
fonte
--parallel
opção se você tiver mais de um núcleo ...)?Uma outra opção é carregar o arquivo em um banco de dados. EG MySQL e MySQL Workbench.
Os bancos de dados são candidatos perfeitos para trabalhar com arquivos grandes
Se o seu arquivo de entrada contiver apenas palavras separadas por uma nova linha, isso não deve ser difícil.
Depois de instalar o banco de dados e o MySQL Workbench, é isso que você precisa fazer.
Primeiro, crie o esquema (isso pressupõe que as palavras não terão mais que 255 caracteres, embora você possa alterá-lo aumentando o valor do argumento). A primeira coluna "idwords" é uma chave primária.
Em segundo lugar, importe os dados: EG Isso importará todas as palavras para a tabela (essa etapa pode demorar um pouco para ser concluída. Meu conselho seria executar um teste com um arquivo de palavras pequenas primeiro e depois de ter certeza de que o formato é o mesmo que o maior (truncar a tabela. IE Limpe-o e carregue o conjunto de dados completo).
Esse link pode ajudar a obter o formato correto para o carregamento. https://dev.mysql.com/doc/refman/5.7/en/load-data.html
EG Se você precisou pular a primeira linha, faria o seguinte.
Por fim, salve o arquivo classificado. Isso pode demorar um pouco, dependendo do seu PC.
Você também pode pesquisar os dados conforme desejar. Por exemplo, as 50 primeiras palavras serão exibidas em ordem crescente (a partir da 0ª ou da primeira palavra).
Boa sorte
Pete
fonte
mywords
levará uma eternidade. Mesmo com oLIMIT
, levará o tempo todo, porque o MySQL terá que passar por todos os valoresmywords
e ordená-los. Para corrigir isso, você deve fazer o seguinte depois de fazerLOAD DATA
. Adicione um índice amywords
. Agora você pode solicitar por essa coluna e não levar um milênio. E é melhor adicionar o índice após o carregamento dos dados, e não no momento em que você criou a tabela (carregamento de dados muito mais rápido).sort
Existem muitos algoritmos usados para classificar arquivos ordenados e não ordenados [ 1 ] .
Como todos esses algoritmos já foram implementados, escolha um programa já testado.
No coreutils (do Linux, mas também disponível para Windows [ 2 ] ), existe o
sort
comando capaz de executar em paralelo sob processadores com vários núcleos: geralmente é o suficiente.Se o seu arquivo for tão grande, você poderá ajudar na divisão do processamento (
split -l
), o arquivo em alguns trechos, possivelmente usando a opção paralela (--parallel
) e classificando os trechos ordenados resultantes com a-m
opção ( classificação por mesclagem ).Uma das muitas maneiras de fazer isso é explicada aqui (arquivo dividido, ordenar pedaços únicos, mesclar pedaços ordenados, excluir arquivos temporários).
Notas:
(Por exemplo, uma classificação de bolha é o algoritmo mais rápido para um arquivo já solicitado - exatamente N -, mas não é eficiente em outros casos).
fonte
Para oferecer uma solução alternativa ao Peter H, existe um programa q que permite comandos no estilo SQL em arquivos de texto. O comando abaixo faria o mesmo (executado no prompt de comando no mesmo diretório que o arquivo), sem a necessidade de instalar o SQL Workbench ou criar tabelas.
c1
é um atalho para a coluna 1.Você pode excluir palavras duplicadas com
e envie a saída para outro arquivo
fonte
Se as palavras em cada linha são de um vocabulário limitado (como o inglês), você pode classificar a lista em O (n + m log m) usando um TreeMap e as contagens de gravação (onde m é o número de valores únicos).
Caso contrário, você pode usar o classificador grande da biblioteca java . Ele divide a entrada em arquivos intermediários classificados e os mescla de maneira eficiente (O geral (nlogn)). Para classificar seu arquivo, fica assim:
Criei um arquivo de 1,7 GB (linhas de 100 m) com 16 palavras geradas aleatoriamente e classifiquei-o como acima em 142s e com base na complexidade computacional O (n log n) do método que estou usando, calculo que 800 GB de 16 palavras seria demore cerca de 24 horas para classificar uma thread no meu laptop i5 de 2,3 GHz com SSD.
fonte