gpt4 book ai didi

c# - numpy 的日志函数发生了什么?有没有办法提高性能?

转载 作者:太空狗 更新时间:2023-10-29 21:08:09 26 4
gpt4 key购买 nike

我有一个大量使用日志函数(用于整数)的计算项目,调用了数十亿次。我发现 numpy 的日志的性能出奇的慢。

以下代码需要 15 到 17 秒才能完成:

import numpy as np
import time

t1 = time.time()
for i in range(1,10000000):
np.log(i)
t2 = time.time()
print(t2 - t1)

但是,math.log 函数花费的时间要少得多,只有 3 到 4 秒。

import math
import time

t1 = time.time()
for i in range(1,10000000):
math.log(i)
t2 = time.time()
print(t2 - t1)

我还测试了 matlab 和 C#,分别需要大约 2 秒和 0.3 秒。

ma​​tlab

tic
for i = 1:10000000
log(i);
end
toc

C#

var t = DateTime.Now;
for (int i = 1; i < 10000000; ++i)
Math.Log(i);
Console.WriteLine((DateTime.Now - t).TotalSeconds);

在python中有什么方法可以提高日志功能的性能吗?

最佳答案

NumPys 函数是为数组设计的,而不是为单个值或标量设计的。它们的开销相当高,因为它们会进行多次检查和转换,这将为大型数组提供速度优势,但这些对于标量来说代价高昂。

如果检查返回的类型,转换就非常明显:

>>> import numpy as np
>>> import math

>>> type(np.log(2.))
numpy.float64
>>> type(math.log(2.))
float

另一方面,math -module 针对标量进行了优化。所以他们不需要那么多检查(我认为只有两个:转换为 float 并检查它是 <= 0 )。这就是为什么 math.lognumpy.log 相比,对于标量 更快.

但是如果你对数组进行操作并且想对数组中的所有元素取对数,NumPy 会快得多。在我的电脑上,如果我计时 np.log 的执行时间在数组上与 math.log 相比列表中的每个项目然后时间看起来不同:

arr = np.arange(1, 10000000)
%timeit np.log(arr)
201 ms ± 959 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

lst = arr.tolist()
%timeit [math.log(item) for item in lst]
8.77 s ± 63.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

所以 np.log在阵列上会快很多数量级(在这种情况下快 40 倍以上)!而且您不需要自己编写任何循环。作为 ufunc np.log也将在多维 numpy 数组上正确工作,并且还允许就地进行操作。

根据经验:如果你有一个包含数千个项目的数组,NumPy 会更快,如果你有标量或只有几十个项目 math + 显式循环会更快。


也不要使用 time用于定时代码。有专门的模块可以提供更准确的结果、更好的统计数据并在计时期间禁用垃圾收集:

我一般用 %timeit 这是一个方便的包装 timeit功能,但它需要 IPython .他们已经方便地显示结果均值和偏差,并进行一些(大部分)有用的统计,例如显示“7 项中的最佳”或“3 项中的最佳”结果。


我最近分析了 another question 的 numpy 函数的运行时行为,其中一些要点也适用于此。

关于c# - numpy 的日志函数发生了什么?有没有办法提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43892586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com