2013-07-20 22 views
8

Birkaç hafta boyunca bu konu üzerinde çalışıyorum ve python bellek sızıntısı hakkında birçok soru okudum ama anlayamıyorum.Python Öldü (büyük olasılıkla bellek sızıntısı)

Yaklaşık 7 milyon satır içeren bir dosyam var. Her satır için bir sözlük oluşturmam gerekiyor. Ne yapıyorum olduğunu

[{'a': 2, 'b':1}{'a':1, 'b':2, 'c':1}] 

...

list = [] 
for line in file.readlines(): 
    terms = line.split(" ") 
    dict = {} 
    for term in terms: 
     if term in dict: 
      dict[term] = dict[term] + 1 
     else: 
      dict[term] = 1 
    list.append(dict.copy()) 
    dict.clear() 
file.close() 

sorun bu çalıştırdığınızda her zaman 6000000 çizgisi etrafında öldürülmeden olmasıdır: Yani şöyle sözlükte listesidir. Aslında ben sadece dict = {} yapıyordum ama ben benzer yazılarını okuduktan sonra dict.clear() yapıyorum, ama bir şey geliştirmedi. Döngüsel referanslarla ilgili bazı yazılar biliyorum ve koduma baktım ama bu problemi görmedim.

Listede 7 milyon sözlük saklamanın Python'da ele alınamayacağından şüphem yok mu? Bütün şeyleri öldürmeden nasıl yönetebileceğime dair her türlü tavsiyeyi takdir ediyorum. Bunun size koduyla elde etmek çalıştığımız şey olduğuna inanıyoruz

from collections import Counter 
with open('input') as fin: 
    term_counts = [Counter(line.split()) for line in fin] 

:

+2

Burada ne elde etmeye çalışıyorsunuz? –

+0

@ThomasOrozco Sorularımı biraz düzenledim, ama yapmaya çalıştığım şey, her satır için terim sözlüğünü saklamaktır. – kabichan

+2

Dosya için _dosya değiştirmeyi denediniz mi? ? – uselpa

cevap

8

deneyin (sürüm 2.7.4 ise).

Bu

+0

Denedim ve hala öldürüldü .. tek fark ettiğim şey senin dosyadan bir değişkeme sahip olduğum tek şey, yani ben fin olarak açık (dosya) ile yaptım: 've geri kalanı aynı. – kabichan

+0

@kabichan İstediğiniz kadar basit bir şey var - veriyi diskte saklamanız gibi bir ses var/DB –

+0

Eğer yapamadığım şeyi yapamadığım için yapamayacağım, o zaman devam edebilirim ve başka bir şey deneyin. Seninkini cevap olarak kabul edeceğim çünkü benzer problemleri çözecek gibi görünüyor. Tavsiyen için teşekkür ederim. – kabichan

1

yoktur ... sayım yapmak Counter kullanır, önce belleğe dosyası yüklenirken .readlines() önler ve/sözlükleri takas listelerine ekleme/atamak/etrafında faffing kesmesiz tek seferde listesi oluşturur Python en az yarı yolda iyi bir çöp toplama yöntemi kullandığı için, bu kadar basit bir kod snippet'iyle bir bellek sızıntısına sahip olmanıza imkan yok. Potansiyel bir sorun, hafızanız bitebiliyor olmanızdır (bu nedenle, yeni başlayanlar için kesinlikle .readlines kullanmaktan kaçının; bunun yerine "my_file satırında" kullanın); Ayrıca bir sözlük aslında çeşitli nedenlerle oldukça az bir bellek kullanır - bir sözlük kasten çarpışmaların azaltılmasına yardımcı olmak için hızlı bir şekilde çok fazla ekleme yapabilmeniz için mevcut anahtar kümenizden önemli ölçüde daha büyük bir karma tablo kullanır. Gerekirse yeni anahtarların, ekleme başına amortize edilmiş O (1) zaman ile. Öldüğünden önce dosyanızın sonuna çok yaklaştığınız için, deneyebileceğiniz bir şey, ilk k-tuple'ını saklamak istediğiniz k tuşlarını içeren 2-tuple k-tuple'ı olarak saklamaktır. ve ikinci k-tuple k tuşları için sizin k sayınızdır. Bir görünüm için

match_idx = [i for i in xrange(len(T[0])) if T[0][i] == my_key] 
if len(match_idx) == 0: 
    # no match, do whatever 
else: #match 
    count = T[1][match_idx[0]] 
    # now do whatever with count 

çalışma süresi: Bu 2-küpe T birinde my_key bir görünüm-up yapmak için size böyle bir şey yapmak gerekeceğini pahasına bazı bellekten tasarruf etmelidir yukarı, arama yapmak zorunda olduğunuz anahtarların sayısında, sabit zaman yerine doğrusal olacaktır (bir sözlük araması yapmak için gereken bir şey önemsiz bir işlem değildir, ancak sabit daha basit bir işlem için sabit bir büyüklükten daha büyüktür.). Anahtarlarınızı sıralı bir şekilde sakladıysanız, anahtarınızı hızlıca bulmak için ikili aramayı kullanabilirsiniz, ancak bu daha fazla kod gerektirecektir ve kısaca python kullandığınızı kabul ediyorum çünkü kısaca kod vermeye eğilimlidir. Bununla birlikte, eğer sözlüklerinizin 6 milyonunu başarıyla oluşturuyorsanız, o zaman ortalama olarak 7 milyonluk sözlüklerinizde çok fazla anahtar bulunmamalıdır. Bu nedenle, veri kümeniz için python kullanmak istiyorsanız, bu, daha fazla belleğe sahip bir makine almadıkça gitmek için tek yol olabilir.