Python 为什么每10万次迭代打印一次会破坏numba的性能?

Python 为什么每10万次迭代打印一次会破坏numba的性能?,python,printing,jit,numba,Python,Printing,Jit,Numba,为什么使用打印每100k次(即仅打印40行!)的代码需要50秒才能运行: import numpy as np from numba import jit @jit def doit(): A = np.random.random(4*1000*1000) n = 300 Q = np.zeros(len(A)-n) for i in range(len(Q)): Q[i] = np.sum(A[i:i+n] <= A[i+n])

为什么使用
打印
每100k次(即仅打印40行!)的代码需要50秒才能运行:

import numpy as np
from numba import jit

@jit
def doit():
    A = np.random.random(4*1000*1000)
    n = 300
    Q = np.zeros(len(A)-n)
    for i in range(len(Q)):
        Q[i] = np.sum(A[i:i+n] <= A[i+n])
        if i % 100000 == 0:  # print the progress once every 100k iterations
            print("%i %.2f %% already done. " % (i, i * 100.0 / len(A)))

doit()


这是一个普遍的事实,即
print
确实可以消除
numba
的好处吗?

如果您尝试使用
@njit
@jit(nopython=True)
编译它,您将看到它是在异常的对象模式下编译的。此版本在我的计算机上运行约1秒,打印语句为:

import numpy as np
from numba import jit

@jit(nopython=True)
def doit():
    A = np.random.random(4*1000*1000)
    n = 300
    Q = np.zeros(len(A)-n)
    for i in range(len(Q)):
        Q[i] = np.sum(A[i:i+n] <= A[i+n])
        if i % 100000 == 0:  # print the progress once every 100k iterations
            print(i , "(",  i * 100.0 / len(A), '% already done)')
将numpy导入为np
从numba导入jit
@jit(nopython=True)
def doit():
A=np.随机.随机(4*1000*1000)
n=300
Q=np.零(len(A)-n)
对于范围内的i(len(Q)):

Q[i]=np.sum(A[i:i+n]如果您尝试使用
@njit
@jit(nopython=True)
编译它,您将看到它是从异常以对象模式编译的。此版本在我的机器上运行大约1秒,并带有print语句:

import numpy as np
from numba import jit

@jit(nopython=True)
def doit():
    A = np.random.random(4*1000*1000)
    n = 300
    Q = np.zeros(len(A)-n)
    for i in range(len(Q)):
        Q[i] = np.sum(A[i:i+n] <= A[i+n])
        if i % 100000 == 0:  # print the progress once every 100k iterations
            print(i , "(",  i * 100.0 / len(A), '% already done)')
将numpy导入为np
从numba导入jit
@jit(nopython=True)
def doit():
A=np.随机.随机(4*1000*1000)
n=300
Q=np.零(len(A)-n)
对于范围内的i(len(Q)):

Q[i]=np.sum(A[i:i+n]您还删除了
i%100000
计算。在您的第一个示例中,您要求循环在每次迭代中执行额外的操作以执行检查,并且当您循环超过400万次时,即使该操作只需要0.01毫秒运行,它总计运行时间约为40秒。实际上,我认为
i%100000
不是问题是,如果你把
print
改为
pass
,速度会快得多。而且
print
本身也不是关键点。相反,将数字转换成字符串是关键点,因为有时速度非常慢。@khelwood计算
i%100000
真的需要10µs吗?如果
,我真的需要ubt这是真的。与
np.sum(a[i:i+300]相比,计算模似乎可以忽略不计@Sraw将数字转换为字符串只会发生40次。我认为这无法解释40秒的时间。您还删除了
I%100000
计算。在您的第一个示例中,您要求循环在每次迭代中做额外的事情来执行检查,当您循环超过400万次时,即使该操作只需要0.01毫秒我第二次运行时,它总共运行了约40秒。事实上,我认为
I%100000
不是问题所在,如果将
print
更改为
pass
,速度会快得多。而且
print
本身也不是关键点。相反,将数字转换为字符串是关键点,因为有时速度非常慢。@khelwood计算
i%100000
真的需要10µs吗?或者如果
计算
?我真的怀疑这是真的。与
np.sum(a[i:i+300]@Sraw将数字转换为字符串只发生了40次。我想这无法解释40秒的原因。谢谢你的回答。在这个例子中,是什么让numba切换到慢速
对象模式而不是保持正常的“快速模式”?是
打印
功能中不支持的字符串格式。感谢您的回答。在本例中,是什么使Nuba切换到慢速
对象模式
而不是保持正常的“快速模式”?是
打印
功能中不支持的字符串格式。