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

Python - scalability with respect to run time and memory usage is important

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

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

当我比较2个脚本的运行ning时间时,我发现如下:

脚本 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 生成器吗?或任何建议或建议?

To meet the requirement, do I need to use python generator?

不,你不知道。脚本 1 没有意义。生成器总是执行一次,return 在第一次迭代中产生一个结果。

Any suggestions or recommendations?

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

  • 复杂度基本上就是"if I double the size of input data (csv file), do I need twice the time? Or four times? Or what"?

  • 并行化意味着以一种易于添加更多资源来解决问题的方式来解决问题。

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

主循环 for line in csvfile: 已经很好地扩展了,除非 csv 文件包含非常长的行。

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

isprime函数可能是你代码中的"hotspot",所以你可以尝试用多线程或子进程并行化它。

将您的分析分成两个离散的正则表达式结果:一个包含 10 个值的小结果和一个包含 10,000,000 个值的大结果。这个问题是关于 match 的平均值 len(),以及关于 csvfilelen()

结果较小 - 10 字节

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

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

结果很大 - 10,000,000 字节

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

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

底线:

如果您要构建一个考虑 运行 时间和内存的函数,那么当问题需要针对不同结果大小的可扩展解决方案时,yield 函数绝对是最佳选择。

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

def each_sentence(text):
    match = re.match(r'[0-9]+', text)
    if match != None:
        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)