Lad*_*dih 4 python performance numpy
import numpy as np
from datetime import datetime
import math
def norm(l):
s = 0
for i in l:
s += i**2
return math.sqrt(s)
def foo(a, b, f):
l = range(a)
s = datetime.now()
for i in range(b):
f(l)
e = datetime.now()
return e-s
foo(10**4, 10**5, norm)
foo(10**4, 10**5, np.linalg.norm)
foo(10**2, 10**7, norm)
foo(10**2, 10**7, np.linalg.norm)
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
0:00:43.156278
0:00:23.923239
0:00:44.184835
0:01:00.343875
Run Code Online (Sandbox Code Playgroud)
似乎当np.linalg.norm多次调用小尺寸数据时,它的运行速度比我的标准函数慢。
其原因何在?
首先:datetime.now()不适合衡量性能,它包括挂机时间,当高优先级进程运行或 Python GC 启动时,您可能会选择一个不好的时间(对于您的计算机),...
Python 中有专用的计时函数/模块:内置timeit模块或%timeitIPython/Jupyter 以及其他几个外部模块(例如perf,...)
让我们看看如果我在您的数据上使用这些会发生什么:
\n\nimport numpy as np\nimport math\n\ndef norm(l):\n s = 0\n for i in l:\n s += i**2\n return math.sqrt(s)\n\nr1 = range(10**4)\nr2 = range(10**2)\n\n%timeit norm(r1)\n3.34 ms \xc2\xb1 150 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n%timeit np.linalg.norm(r1)\n1.05 ms \xc2\xb1 3.92 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n\n%timeit norm(r2)\n30.8 \xc2\xb5s \xc2\xb1 1.53 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\n%timeit np.linalg.norm(r2)\n14.2 \xc2\xb5s \xc2\xb1 313 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n对于短迭代来说它并不慢,它仍然更快。但请注意,如果您已经拥有 NumPy 数组,那么 NumPy 函数的真正优势就会显现:
\n\na1 = np.arange(10**4)\na2 = np.arange(10**2)\n\n%timeit np.linalg.norm(a1)\n18.7 \xc2\xb5s \xc2\xb1 539 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n%timeit np.linalg.norm(a2)\n4.03 \xc2\xb5s \xc2\xb1 157 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n是的,现在速度快多了。18.7us 与 1ms - 对于 10000 个元素几乎快了 100 倍。这意味着您的示例中的大部分时间np.linalg.norm都花在将 转换range为np.array.