Python过多的内存使用与简单的脚本

时间:2016-04-08 11:54:47

标签: python memory

我正在编写一个非常简单的脚本,它将计算文件中出现的次数。文件大小约为300Mb(1500万行),有3列。由于我逐行读取文件,因此我不希望python使用大量内存。最大值将略高于300Mb以存储计数字典。

但是,当我查看活动监视器时,内存使用量会超过1.5Gb。我究竟做错了什么 ?如果这是正常的,有人可以解释一下吗?感谢

import csv
def get_counts(filepath):
    with open(filepath,'rb') as csvfile:
        reader = csv.DictReader(csvfile, fieldnames=['col1','col2','col3'], delimiter=',')
        counts = {}
        for row in reader:

            key1 = int(row['col1'])
            key2 = int(row['col2'])

            if (key1, key2) in counts:
                counts[key1, key2] += 1
            else:
                counts[key1, key2] = 1

    return counts

3 个答案:

答案 0 :(得分:2)

我认为这很好,Python在你的情况下使用了这么多内存。这是我的机器上的测试:

Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
>>> file_size = 300000000
>>> column_count = 10
>>> average_string_size = 10
>>> row_count = file_size / (column_count * average_string_size)
>>> row_count
3000000
>>> import os, psutil, cPickle
>>> mem1 = psutil.Process(os.getpid()).memory_info().rss
>>> data = [{column_no: '*' * average_string_size for column_no in xrange(column_count)} for row_no in xrange(row_count)]
>>> mem2 = psutil.Process(os.getpid()).memory_info().rss
>>> mem2 - mem1
4604071936L
>>>

因此,包含10个长度为10的字符串的3000000 dict的完整列表正在使用更多4GB的RAM。

在您的情况下,我不认为csv数据占用RAM。这是你的counts词典。

另一种解释是,从csv文件中逐个读取的dicts不会立即被垃圾收集(尽管我不确认)。

在任何情况下都使用专门的工具来查看占用内存的内容,例如https://pypi.python.org/pypi/memory_profiler

P.S。而不是做

        if (key1, key2) in counts:
            counts[key1, key2] += 1
        else:
            counts[key1, key2] = 1

待办事项

from collections import defaultdict
...
counts = defaultdict(int)
...
counts[(key1, key2)] += 1

答案 1 :(得分:0)

你可以尝试类似的东西:

import csv

def get_counts(filepath):

    data = csv.reader(open(filepath), delimiter=',')
    # Remove the first line if headers
    fields = data.next()
    counts = {}

    [count[row[0], row[1]] = count.get((row[0], row[1]), 0) + 1 for row in data]

    return counts

答案 2 :(得分:0)

试试这个

from collection import Counter
import csv

myreader = csv.reader( open(filename, 'r'))
Counter([each[:-1] for row in myreader] )

希望这有帮助。