为什么numpy中的log2和log1p比log和log10快得多?

问题描述 投票:18回答:4

[在玩this question时,我注意到我无法解释np.log2np.log2np.log的相对性能:

np.log

np.log10np.log10In [1]: %%timeit x = np.random.rand(100000) ....: np.log2(x) ....: 1000 loops, best of 3: 1.31 ms per loop In [2]: %%timeit x = np.random.rand(100000) np.log(x) ....: 100 loops, best of 3: 3.64 ms per loop In [3]: %%timeit x = np.random.rand(100000) np.log10(x) ....: 100 loops, best of 3: 3.93 ms per loop 快3倍。可能更违反直觉的是,计算ln(x + 1)np.log2np.log

相当。
np.log10

我在numpy v1.10.1和v1.8.2。中获得了几乎相同的计时。

是否有针对这些运行时性能差异的直观解释?

python performance numpy glibc logarithm
4个回答
10
投票

我发现您的问题非常有趣,因此我花了几个小时进行一些研究;我想我已经找到了有关性能差异因为它适用于整数的解释(感谢您np.log1p(x)的注释)-目前尚不清楚如何将推理扩展到浮点数:

[计算机使用2为基数-根据参考链接的文章,log2的计算是一个4个处理器周期的过程-log10的计算需要将log2(val)乘以1 / log2(10),这又增加了5个周期。] >

查找log2是np.log1p(x)的问题。

((大约23分钟后的视频开始)。

位hacks:np.log2

位hacks:In [4]: %%timeit x = np.random.rand(100000) np.log1p(x) ....: 1000 loops, best of 3: 1.46 ms per loop

整数对数10为底,首先使用上面找到对数基的技术2.通过关系log10(v)= log2(v)/ log2(10),我们需要将其乘以1 / log2(10),大约是1233/4096,即1233,然后右移12.由于IntegerLogBase2会向下舍入,因此需要添加一个。最后,由于值t只是一个近似值,可能会偏离一,通过减去v

此方法比IntegerLogBase2多执行6个操作。可能是通过修改日志加快(在具有快速内存访问权限的计算机上)上面的基于2的表查找方法,以便条目包含什么为t计算(即预加,-mulitply和-shift)。这样做总共只需要9个操作就可以找到10个对数,假设使用了4个表(v的每个字节一个)。

注意:使用DeBruijn序列查找和移位技术来计算此Matteo Italia中的log2 ((从第36分钟开始的视频)。

请注意,此StackOverflow帖子演示了finding the index of the least significant bit of a value

注意:我没有检查numpy源代码以验证它确实实现了类似的技术,但令人惊讶的是它没有实现。实际上,从OP帖子的评论中,Find integer log base 10 of an integer已检查:

实际上numpy使用glibc中的math.h,您将看到相同的区别在C / C ++中,如果您使用math.h / cmath.h。你可以找到评论很好的这两个功能的源代码,例如Find the log base 2 of an N-bit integer in O(lg(N))MIT video: Lec 2 | MIT 6.172 Performance Engineering of Software Systems, Fall 2010a method to make efficient log2 calculations truly cross platform with C++[9]


7
投票

这只是一个注释,但长于注释。显然,这与您的特定安装有关:


4
投票

免责声明:我既不是可信的,也不是官方消息来源。


2
投票

(可能应该是评论,但时间太长...)

© www.soinside.com 2019 - 2024. All rights reserved.