为啥这个脚本会随着输入量的增加而减慢每个项目的速度?

Posted

技术标签:

【中文标题】为啥这个脚本会随着输入量的增加而减慢每个项目的速度?【英文标题】:Why is this script slowing down per item with increased amount of input?为什么这个脚本会随着输入量的增加而减慢每个项目的速度? 【发布时间】:2015-06-12 18:50:11 【问题描述】:

考虑以下程序:

#!/usr/bin/env pypy

import json
import cStringIO
import sys

def main():
    BUFSIZE = 10240
    f = sys.stdin
    decoder = json.JSONDecoder()
    io = cStringIO.StringIO()

    do_continue = True
    while True:
        read = f.read(BUFSIZE)
        if len(read) < BUFSIZE:
            do_continue = False
        io.write(read)
        try:
            data, offset = decoder.raw_decode(io.getvalue())
            print(data)
            rest = io.getvalue()[offset:]
            if rest.startswith('\n'):
                rest = rest[1:]
            decoder = json.JSONDecoder()
            io = cStringIO.StringIO()
            io.write(rest)
        except ValueError, e:
            #print(e)
            #print(repr(io.getvalue()))
            continue
        if not do_continue:
            break

if __name__ == '__main__':
    main()

这是一个测试用例:

$ yes '' | pv | pypy  parser-test.py >/dev/null

如您所见,当您向其添加更多输入时,以下脚本会变慢。 cPython 也会发生这种情况。我尝试使用 mprof 和 cProfile 来分析脚本,但我没有发现任何提示。有人知道吗?

【问题讨论】:

为什么不会输入越多就会越慢? 我试图让它迭代 - 获取一个对象,打印它并丢弃它。我不希望那里有内存泄漏。你能看到一个吗? 我不是在谈论内存泄漏!输入越长,处理的时间就越长,除非你的算法是O(1)。还是您的意思是随着输入长度的增加,每个项目需要更长的时间? 每个项目确实需要更长的时间。 也许你可以更清楚一点?例如,使用每单位大小的时间显示一系列输出大小的输出? 【参考方案1】:

显然字符串操作减慢了它的速度。而不是:

        data, offset = decoder.raw_decode(io.getvalue())
        print(data)
        rest = io.getvalue()[offset:]
        if rest.startswith('\n'):
            rest = rest[1:]

最好这样做:

        data, offset = decoder.raw_decode(io.read())
        print(data)
        rest = io.getvalue()[offset:]
        io.truncate()
        io.write(rest)
        if rest.startswith('\n'):
            io.seek(1)

【讨论】:

【参考方案2】:

您可能希望在迭代结束时(写入后)关闭您的 StringIO。

io.close()

StringIO 的内存缓冲区在关闭后将释放,否则将保持打开状态。这可以解释为什么每个额外的输入都会减慢您的脚本速度。

【讨论】:

当然,或者立即发布 if-else 语句。每次迭代只要把它靠近某个地方就可以让缓冲区保持足够的空闲。

以上是关于为啥这个脚本会随着输入量的增加而减慢每个项目的速度?的主要内容,如果未能解决你的问题,请参考以下文章

当计算相同时,为啥 R 会随着时间的推移而减慢?

Lapply 随着循环次数的增加而减慢

UTF-8 内容类型元标记会减慢页面加载速度,为啥?

为啥 TensorFlow 的 `tf.data` 包会减慢我的代码速度?

oracle中加索引会不会加快更新的速度?有人说会减慢更新速度?谁知道为啥吗?

当访问遍历记录集时,它是不是会随着索引的增加而变慢,为啥?