提高numpy三角函数的运算性能

时间:2016-01-02 18:22:16

标签: python performance numpy trigonometry

我有一个相当大的代码,我需要优化。在使用<div ID="BOX" style="width:100%"></div> <script> var body=document.getElementById('BOX'); for (n=0;n<15;n++){ var box=document.createElement('DIV'); box.style.width='20px'; box.style.height='20px'; v=n.toString(16); box.style.background='#'+v+v+v+v+v+v; body.appendChild(box); } </script> 进行一些分析之后,我发现占用最多处理时间的行(它被执行了数千次)就是这一行:

time.time()

其中所有变量都可以随机定义:

A = np.cos(a) * np.cos(b) - np.sin(a) * np.sin(b) * np.sin(c - d)

有没有办法提高N = 5000 a = np.random.uniform(0., 10., N) b = np.random.uniform(0., 50., N) c = np.random.uniform(0., 30., N) d = np.random.uniform(0., 25., N) 计算的效果?由于我已经在使用A,我几乎没有想法。

2 个答案:

答案 0 :(得分:7)

通过使用product-to-sum trig. identities,您可以减少三角形的数量。函数调用。在下文中,func1func2会计算相同的值,但func2会减少对trig的调用。功能

import numpy as np

def func1(a, b, c, d):
    A = np.cos(a) * np.cos(b) - np.sin(a) * np.sin(b) * np.sin(c - d)
    return A

def func2(a, b, c, d):
    s = np.sin(c - d)
    A = 0.5*((1 - s)*np.cos(a - b) + (1 + s)*np.cos(a + b))
    return A

这是与N = 5000的时间比较:

In [48]: %timeit func1(a, b, c, d)
1000 loops, best of 3: 374 µs per loop

In [49]: %timeit func2(a, b, c, d)
1000 loops, best of 3: 241 µs per loop

答案 1 :(得分:3)

您是否尝试使用Numba,Cython,Pythran或其他任何Python加速器?

我和Pythran做了一些测试。结果如下:

原始代码:

  • Python + numpy:1000次循环,最佳3次:每循环1.43毫秒
  • Pythran:1000循环,最佳3:777usec每循环
  • Pythran + SIMD:1000次循环,最佳3:488次循环使用

Warren提供的代码:

  • Python + numpy:1000循环,最佳3:每循环1.05毫秒
  • Pythran:1000循环,最佳3:646每循环usec
  • Pythran + SIMD:1000次循环,最佳3:425次循环使用

这是在N = 5000

的情况下完成的
  • 更新*:

以下是代码:

# pythran export func1(float[], float[], float[], float[])
# pythran export func2(float[], float[], float[], float[])
import numpy as np

def func1(a, b, c, d):
    A = np.cos(a) * np.cos(b) - np.sin(a) * np.sin(b) * np.sin(c - d)
    return A

def func2(a, b, c, d):
    s = np.sin(c - d)
    A = 0.5*((1 - s)*np.cos(a - b) + (1 + s)*np.cos(a + b))
    return A

命令行:

$ pythran test.py  # Default compilation
$ pythran test.py -march=native -DUSE_BOOST_SIMD  # Pythran with code vectorization