2016-12-21 3 views
2

큰 파일 (~ 450MB -> 129,000 줄 및 457,000,000 자)이 있는데이 파일을 사용하여 작업하려고하면 Memory Error가 발생합니다. 내 코드는큰 텍스트 자료로 작업 할 때 메모리 오류

입니다.
docDict = {} 
ind = 1 

with open('somefile.txt',encoding='utf-8') as f: 
    for line in f: 
     data = line.split(' ') 
     docDict[ind] = data 
     ind+=1 

나는 this을 보았지만 한 줄씩 파일을 읽었습니다.

답변

0

memory error은 파일을 한 줄씩 읽더라도 해당 내용을 사전 docDict에 저장하므로 메모리에 저장됩니다.

이 사전으로 무엇을 할 것인지 모르겠다. 각 줄을 읽은 다음 그 결과를 변수에 저장하는 것이 좋습니다 (프로세스가 많이 압축되는 경우). 또는 파일이나 데이터베이스에 직접 저장할 수 있습니다.

희망이 있습니다. 다음에 봐 !

1

코드에서 데이터 구조의 오버 헤드를 테스트하기 위해 다음 테스트 프로그램을 작성했습니다. 텍스트 파일이 상대적으로 짧은 행의 ASCII 인코딩으로 N 메가 바이트라고 가정합니다. (내 실제 메모리 뛰쳐 후 나는 150 (450)에서 N을 변경했다.) 결과에

import sys 

MB = 1024 * 1024 

line = "the quick brown fox jumps over the lazy dog" 
megs = 150 
nlines = (megs * MB)/len(line) 

d = {} 
for i in xrange(nlines): 
    d[i] = line.split(' ') 

dict_size = sys.getsizeof(d) 
list_size = sum(sys.getsizeof(a) for a in d.items()) 
item_size = sum(sum(sys.getsizeof(s) for s in a) for a in d.items()) 

print " dict:", dict_size/float(MB), "MB" 
print "lists:", list_size/float(MB), "MB" 
print "items:", item_size/float(MB), "MB" 
print "total:", (dict_size + list_size + item_size)/float(MB), "MB" 

:

dict: 192.00 MB 
lists: 251.16 MB 
items: 669.77 MB 
total: 1112.9 MB 

활동 모니터를보고, 파이썬 프로세스는 메모리 사용량 2 기가 바이트 초과 , 그래서 또한 계산되지 않은 약간의 기억이있다. malloc 구현의 아티팩트가있을 수 있습니다.

나는 C++에서 같은 프로그램을 구현 :
#include <string> 
#include <vector> 
#include <unordered_map> 

int main() 
{ 
    int const MB = 1024 * 1024; 

    std::string const line = "the quick brown fox jumps over the lazy dog"; 
    std::vector<std::string> const split = { 
     "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" 
    }; 

    int const megs = 150; 
    int const nlines = (megs * MB)/line.size(); 

    std::unordered_map<int, std::vector<std::string>> d; 
    for (int i = 0; i < nlines; ++i) { 
     d[i] = split; 
    } 
} 

clang++ -O3 컴파일이는 1GB의 메모리에 대한 사용. C++에는 sys.getsizeof()이 없으므로 메모리 사용량을 줄이기 위해 더 많은 작업이 필요하며 그 작업을 수행하지 않았습니다.

2 배의 등가 C++ 메모리가 실제로는 Python에서 꽤 좋은 결과이므로 cPython 구현에 대한 사전 편집 주석을 제거하고 있습니다.

주 문제점은 줄을 짧은 문자열의 배열로 저장하고 있다고 생각합니다. 줄을 전체 문자열로 저장하고 필요에 따라 나누는 것이 가능합니까? 한꺼번에 줄이지는 않습니까?

프로그램의 최종 목표는 무엇입니까?

+0

불행히도 각 라인은 적어도 100 단어에서 1000 단어까지 !! 내 코드를 어떻게 복잡하게 할 수 있습니까? – Arman

+0

사실 프로그램을'line = 10 * '으로 변경하면 게으른 개가'''위로 뛰어 오릅니다. 메모리 사용량은'items'에도 많이 떨어집니다. 이것은 놀랍습니다.''dict''과''list'' 오버 헤드가 떨어질 것으로 기대합니다. – japreiss

+0

은 C++ 비교를 추가했으며 새로운 결론은 편집을 참조하십시오. – japreiss