首页 > 解决方案 > 为什么在 PyPy 中从用户输入构建列表并打印其内容比 CPython 慢得多?

问题描述

我正在为 CodeForces 中的一个问题编写代码,我提交了这段代码以在 PyPy 中运行:

import math
a=[]
b=[]
t=int(input())
for i in range(t):
    n=float(input())
    a.append(math.floor(n))
    b.append(math.ceil(n))
l=0-sum(a)
i=0
while i<len(a):
    if l>0 and a[i]!=b[i]:
        print(b[i])
        l-=1
    else:
        print(a[i])
    i+=1

但是,我得到了“超出时间限制”的判决,执行时间超过 1 秒。

当由 CPython 解释器运行时,相同的代码运行时间不到 600 毫秒。

据我了解,PyPy 通常比 Python 快。为什么 CPython 对于这段代码会更快?

标签: pythoncpythonpypy

解决方案


欢迎来到堆栈溢出!简而言之,在这种情况下,PyPy 输给 CPython 的原因是我们运行的 Python 代码并没有真正计算太多,而是所有时间都花在了输入/输出上(首先是一个循环input(),然后是一个循环print())。这可能是花费时间的主要部分。PyPy 的输入/输出例程不如 CPython 的优化,这就是为什么它有点慢的原因。当你编写的 Python 代码花时间在 Python 中进行计算时,你可以猜到 PyPy 会战胜 CPython,有时是大规模的。

“在 Python 中进行计算”的反面有时被称为“运行库代码”——这包括诸如输入/输出之类的东西,或者更一般地说,任何单个 Python 函数调用调用大量 C 代码的东西。请注意,与直觉相反,这还包括对非常非常大的整数进行算术运算,因为每个操作都需要大量 C 代码。相反的极端示例是对“小”整数进行算术运算,最高可达sys.maxsize,因为 PyPy JIT 可以将每个操作直接映射到一条 CPU 指令。

总而言之,PyPy在纯 Python 中花费一些时间时很好——不一定总是如此。例如,非平凡的纯 Python Web 服务器往往会从 PyPy 中受益匪浅:原始套接字输入/输出确实有点慢,但处理查询和构建响应的所有逻辑要快得多,这很容易执行时间的主要部分。


推荐阅读