简体   繁体   English

为什么在PyPy中根据用户输入构建列表并打印其内容比CPython要慢得多?

[英]Why is building a list from user input and printing its contents much slower in PyPy than CPython?

I was coding for a problem in CodeForces, and I submitted this code to run in PyPy: 我在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

However, I was given a "time limit exceeded" verdict, with the execution taking over 1 second. 但是,我得到了“超过时间限制”的裁决,执行时间超过1秒。

The same code ran in under 600 ms when run by the CPython interpreter. 由CPython解释器运行时,同一代码在600毫秒内运行。

From what I understand, PyPy is usually faster than Python. 据我了解,PyPy通常比Python快。 Why would CPython be faster for this code? 为什么CPython对于此代码会更快?

Welcome to Stack Overflow! 欢迎使用Stack Overflow! In two words, the reason that PyPy looses to CPython in this case is that the Python code we are running is not really computing much, but instead all the time is spent doing input/output (first with a loop of input() , then a loop of print() ). 用两个词来说,在这种情况下PyPy对CPython松散的原因是我们正在运行的Python代码实际上并没有太多的计算,而是将所有的时间都花在了输入/输出上(首先是使用input()循环,然后是print()循环)。 This is likely the major part of where the time is spent. 这可能是花费时间的主要部分。 PyPy's routines for input/output are not as well optimized as CPython's, which is the reason for why it is somewhat slower. PyPy的输入/输出例程没有CPython的优化,这就是为什么它慢一些的原因。 You can have a guess that PyPy will win over CPython, sometimes massively, when the Python code that you wrote is spending time doing computations in Python. 您可能会猜想,当您编写的Python代码花时间在Python中进行计算时,PyPy会胜过CPython,有时会胜过CPython。

The opposite of "doing computations in Python" is sometimes called "running library code"---this includes things like input/output, or more generally anything where a single Python function call invokes quite a lot of C code. “在Python中进行计算”的反义词有时被称为“运行库代码” ---它包括输入/​​输出之类的东西,或更普遍地讲,其中单个Python函数调用会调用大量C代码的东西。 Note that, counter-intuitively, this also includes doing arithmetic on very, very large integers, because that requires a lot of C code for every single operation. 请注意,与直觉相反,这还包括对非常大的整数进行算术运算,因为对于每个单个操作都需要大量C代码。 The opposite extreme example would be doing arithmetic on "small" integers, up to sys.maxsize , because the PyPy JIT can map every operation directly to one CPU instruction. 相反的极端示例是对直到sys.maxsize “小”整数进行算术运算,因为PyPy JIT可以将每个操作直接映射到一条CPU指令。

In summary, PyPy is good where there is some time spent in pure Python---not necessarily all the time. 综上所述,PyPy好那里是纯Python花了一些时间---不一定所有的时间。 For example, non-trivial pure-Python web servers tend to benefit a lot from PyPy: the raw socket input/output is indeed a bit slower, but all the logic to process the queries and build responses is much faster, and that's easily the major part of the execution time. 例如,非平凡的纯Python Web服务器往往会从PyPy中受益匪浅:原始套接字的输入/输出确实要慢一些,但是处理查询和建立响应的所有逻辑都快得多,这很容易执行时间的主要部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM