返回迭代器vs返回Python中的整个列表?

时间:2016-02-13 01:34:43

标签: python performance time-complexity space-complexity

我测试了一些代码,知道哪一个有效,返回迭代器并返回整个列表。

该程序是关于阅读.txt文件的所有行(非常大的大小)并创建字数统计字典(Python3.4)。

1.Returning iterator

from collections import defaultdict
import time

def create_word_cnt_dict(line_iter):
    doc_vector = defaultdict(int)
    for line in line_iter:
        for word in line.split():
            doc_vector[word] += 1
    return dict(doc_vector)

def read_doc(doc_file):
    with open(doc_file) as f :
        while True:
            line = f.readline()
            if not line:
                break
            yield line

t0 = time.time()
line_iter = read_doc("./doc1.txt")
doc_vector = create_word_cnt_dict(line_iter)
t1 = time.time()
print(t1-t0)

需要3.765739917755127

2.返回整个列表

from collections import defaultdict
import time

def create_word_cnt_dict(line_list):
    doc_vector = defaultdict(int)
    for line in line_list:
        for word in line.split():
            doc_vector[word] += 1
    return dict(doc_vector)

def read_doc1(doc_file):
    with open(doc_file) as f :
        lines = f.readlines()
        return lines

t0 = time.time()
lines = read_doc1("./doc1.txt")
doc_vector = create_word_cnt_dict(lines)
t1 = time.time()
print(t1-t0)

需要3.6890149116516113

如您所见,返回整个列表要快得多。

但就内存使用而言,返回迭代器比撤回整个列表更有效。

在本书Effective Python中,它建议返回迭代器以有效使用内存。但我认为现在时间复杂性比空间复杂性更重要,因为今天的计算机有足够的内存。

请给我一些建议。

3 个答案:

答案 0 :(得分:1)

在这种情况下,我认为你对#34更快的解释"与我的不同。 。 。时间差异大约为几个百分点,这不是很大(除非您的程序运行小时,否则用户可能不会注意到,然后差异无关紧要。)

认为迭代器为您提供了更大的灵活性。如果您想在处理某一行时停止读取行,该怎么办?在这种情况下,迭代器可能是2倍或更快的因素,因为你已经获得了“短路”的能力。

对于短路原因和记忆,我更喜欢这里的发电机功能。

另请注意,您的时间可能因您正在阅读文件而产生偏差。 readlines可能会更高效,因为python可以读取比通常更大的块中的文件,这意味着对操作系统的调用更少。许多其他应用程序不会有这种过剩......

答案 1 :(得分:1)

取决于

如果我们谈论的是相对少量的数据,那么时间复杂性也不会有所不同。

考虑大量数据,我不是在谈论GbsTBs,这是Google和Facebook等大公司每天需要处理的更大的数据集,您认为space complexity 1}}不算time complexity吗?

空间我们不是在谈论存储内存,而是RAM

所以你的问题非常广泛,这取决于应用程序,你要使用的数据量和你的要求。对于相对较小的数据集,我不认为时间复杂性将是一个巨大的空间复杂性。

答案 2 :(得分:0)

性能差异实际上很小。

鉴于此,一个好的程序员会选择生成器版本,因为它很健壮。

如果你啜饮整个文件,你就会设置一个陷阱。在未来的某个时刻,有人(也许你)会尝试传入1GB或10GB,然后他们会被搞砸,然后咒骂“为什么??????”