【问题标题】:GAE Python code MUCH slower in production than locallyGAE Python 代码在生产中比本地慢得多
【发布时间】:2017-01-22 12:14:56
【问题描述】:

在我的 Python GAE 应用程序中,以下 sn-p 代码在生产中比在本地运行时慢得多。处理过程如下:

  1. 在 POST 中加载了大约 1 MB 的文本文件。文本文件的每一行都是一个“项目”。
  2. 我的代码从文本文件创建项目列表并检查重复项和有效性(通过与已编译的 RE 进行比较)。

代码如下:

def process_items(self, text):
    item_list = text.split()
    item_set = set()
    n_valid = 0
    n_invalid = 0
    n_dups = 0
    out = ""
    for item in item_list:
        if item in item_set:
            n_dups += 1
            out += "DUPLICATE: %s\n" % item
        elif valid_item(item): # This compares against a compiled RE
            item_set.add(item)
            n_valid += 1
            out += "%s\n" % item
        else:
            n_invalid += 1
            out += "INVALID: %s\n" % item
    return out

当我在本地开发服务器上运行此程序时,处理一个 50,000 行的 1MB 文件需要 5 秒。

当我在生产环境中运行它时,同一个文件会占用一分钟多的时间,并且请求会超时。文件上传只需要大约一秒钟,所以我知道瓶颈是上面的代码。

过去,生产代码的速度与我的本地代码差不多。我认为这段代码没有改变,所以我怀疑 Google 端可能发生了变化。

知道为什么这段代码现在在生产中要慢得多吗? 我能做些什么来让这段代码更快?我需要向用户返回一个带注释的文件,指出哪些行是重复的,哪些行是无效的。

编辑:

针对 mgilson 的评论,我尝试了以下代码,它在执行时间上产生了巨大的差异!之前在一分钟后超时的处理现在只需要大约 5 秒。 GAE 仍然比预期慢(即使考虑到相对较慢的服务器 CPU),但是有了改进的算法,现在对我来说已经无所谓了。

def process_items(self, text):
    item_list = text.split()
    item_set = set()
    n_valid = 0
    n_invalid = 0
    n_dups = 0
    for i, item in enumerate(item_list):
        item = item.strip()
        if item in item_set:
            n_dups += 1
            item_list[i] = "DUPLICATE: %s" % item
        elif valid_item(item): # This compares against a compiled RE
            item_set.add(item)
            n_valid += 1
            item_list[i] = item
        else:
            n_invalid += 1
            item_list[i] = "INVALID: %s" % item
    return "\n".join(item_list)

【问题讨论】:

  • 比较本地运行和在 GAE 上运行并不公平。根据您设置的instance class,您的 CPU 限制可能低至 600MHz。大多数个人计算机比现在快显着可能 有帮助的一个显而易见的优化是将结果累积在一个列表中,并在末尾累积return "".join(results),而不是使用+=。例如,请参阅Why is ''.join() faster than += in Python? ...
  • 使process_items 生成器yielding 一次一行也可以通过避免缓慢的+= 来加快其整体处理时间
  • @mgilson,我的 Mac 是 2.2 GHz,因此它比 GAE 快 3.7 倍。对于这个 Python 代码,我的 Mac 至少比 GAE 快 12 倍。尽管我意识到许多因素使它成为不完美的比较,但这似乎仍然是一个很大的差异。
  • 从运行到运行所用的时间是否一致。也是一个实例正在运行,或者您是否有启动时间。尝试创建一个新的 appengine 实例并在那里测试你的性能。您可能始终处于受到其他服务冲击的节点上。这是一个直接的 CPU 任务。
  • @TimHoffman,我在一个仅供我使用的实例上连续执行了几次,因此启动时间不是一个因素。从昨天到今天,以及每次后续的几次运行,它都是一致的。

标签: python performance google-app-engine


【解决方案1】:

GAE 生产运行速度比本地运行慢一点也不意外 - 根据您的 instance class,您的生产 CPU 可能会被限制为低至 600MHz,这比大多数开发人员计算机要慢得多。

可以做的一件事就是将结果累积到一个列表中(或从生成器中生成),然后使用str.join 获得完整结果:

def process_items(self, text):
    item_list = text.split()
    item_set = set()
    n_valid = 0
    n_invalid = 0
    n_dups = 0
    out = []
    for item in item_list:
        if item in item_set:
            n_dups += 1
            out.append("DUPLICATE: %s\n" % item)
        elif valid_item(item): # This compares against a compiled RE
            item_set.add(item)
            n_valid += 1
            out.append("%s\n" % item)
        else:
            n_invalid += 1
            out.append("INVALID: %s\n" % item)
    return "".join(out)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多