Python-关于运行时间和内存使用的可伸缩性很重要

时间:2019-02-27 04:22:32

标签: python generator yield-keyword

我有python脚本来过滤csv文件中的大量数据。该要求要求考虑运行时间和内存使用方面的可伸缩性。

我写了2个脚本,它们都可以很好地过滤数据。考虑到可伸缩性,我决定使用python生成器,因为它使用迭代器并且不会在内存中保存太多数据。

当我比较两个脚本的运行时间时,发现以下内容:

脚本1-使用生成器-需要更多时间-0.0155925750732s

def each_sentence(text):
    match = re.match(r'[0-9]+', text)
    num = int(text[match.start():match.end()])
    if sympy.isprime(num) == False:
        yield text.strip()

with open("./file_testing.csv") as csvfile:
    for line in csvfile:
        for text in each_sentence(line):
            print(text)

脚本2-使用拆分并且不使用生成器-花费更少的时间-0.00619888305664

with open("./file_testing.csv") as csvfile:
for line in csvfile:
    array = line.split(',')
    num = int(array[0])
    if sympy.isprime(num) == False:
        print line.strip()

为了满足要求,我需要使用python生成器吗?或任何建议或建议?

2 个答案:

答案 0 :(得分:1)

  

为了满足要求,我需要使用python生成器吗?

不,你不知道。脚本1没有意义。生成器始终执行一次,并在第一次迭代中返回一个结果。

  

有什么建议或建议吗?

您需要了解三件事:复杂性,并行化和缓存。

  • 复杂性基本上是指“如果我将输入数据(csv文件)的大小加倍,我需要两倍的时间吗?还是需要四倍的时间?或者什么?”?

  • 并行化意味着以一种轻松地添加更多资源来解决问题的方式来攻击问题。

  • 缓存很重要。如果您不必一直重新创建所有内容,那么事情将会变得更快,但是您可以重新使用已经生成的内容。

除非csv文件包含非常长的行,否则主循环for line in csvfile:已经可以很好地缩放。

脚本2包含一个错误:如果一行中的第一个单元格不是整数,那么int(array[0])将引发值错误。

isprime函数可能是代码中的“热点”,因此您可以尝试将其与多个线程或子进程并行化。

答案 1 :(得分:1)

将您的分析分为两个离散的正则表达式结果:带有10个值的小结果和带有10,000,000值的大结果。这个问题与len()的平均match有关,与len()的{​​{1}}有关。

结果很小-10个字节

第一个代码块的运行时间较慢,并且内存使用量相对较低。

第二个代码块将具有更快的运行时间,并且还相对地较低的内存使用量

具有较大的结果-10,000,000字节

第一个代码块的运行时间较慢,并且很少的内存使用情况。

第二个代码块将具有更快的运行时间,并且很大的内存使用情况。

底线:

如果应该考虑运行时间和内存来构建函数,那么当问题需要针对不同结果大小的可伸缩解决方案时,yield函数无疑是最好的选择。

关于可伸缩性的另一个问题:如果结果等于None怎么办?我将代码稍微修改如下:

csvfile