python计算两个数的和差积商_在Python(和Cython)中计算两个矩阵的点积的最快方法是什么...

本文探讨了如何使用Cython提高Python中计算两个矩阵点积的效率。通过对比不同方法,展示了静态类型和Cython优化如何显著减少执行时间。实验结果显示,Cython优化后的版本比原始Python代码快了多个数量级,尤其是在处理大型矩阵时。

您应该注释(即,静态类型)所有可能的变量。如果您愿意,以下是我的解决方案:# mydot.pyx

import numpy as np

cimport cython

def dot_1(a, b):

c = [[0 for j in range(len(b[i]))] for i in range(len(a))]

for i in range(len(c)):

for j in range(len(c[i])):

t = 0

for k in range(len(b)):

t += a[i][k] * b[k][j]

c[i][j] = t

return c

@cython.boundscheck(False) # turn off bounds-checking

@cython.wraparound(False) # turn off negative index wrapping

def dot_2(double[:, :] A, double[:, :] B):

cdef Py_ssize_t M = A.shape[0]

cdef Py_ssize_t Na = A.shape[1]

cdef Py_ssize_t Nb = B.shape[0]

cdef Py_ssize_t K = B.shape[1]

assert Na == Nb

result = np.empty((M, K), dtype='d')

cdef double[:, :] C = result

cdef double t

for m in range(M):

for k in range(K):

t = 0

for n in range(Na):

t += A[m, n] * B[n, k]

C[m, k] = t

return result

以及

^{pr2}$

当您运行cython annotate mydot.pyx时,Cython将生成一个HTML文件来注释Cython代码。在那里,黄色高亮显示越深,生成的C代码的开销(Python)就越多。您可以将这两个解决方案(特别是for循环)相互比较。在

运行python app.py也会给你更快的结果。当然,如果您提供的输入值小于某个阈值,那么您将看不到二者之间有意义的速度差异,因为您没有进行足够的迭代。但是,在某个阈值之后,速度差异应该是显著的,因为循环中的每个迭代对于您的版本来说都是昂贵的(参见较深的黄色线)。在

最后一点要说的是,正如这个问题下的每个人都建议的那样,当你提供具有更大维度的矩阵时,numpy的函数应该更高效——它们使用的是来自底层BLAS和LAPACK实现的分块(子)矩阵操作,而不是天真地逐个迭代索引。在

注:如果你想让dot_2不仅专门化doubleS,而且还想专门化其他有意义的算术类型,比如intS和{}S,那么应该检查Cython的fused types。在

编辑。因为我的回答后来被选为答案,所以我想举一个大尺寸输入的例子。如果不是上面的app.py,而是使用以下内容:# app.py

import pyximport

from numpy import array, random as rnd

from scipy import median

from timeit import repeat

pyximport.install()

from mydot import dot_1, dot_2

M = 100

N = 100

K = 1

a = rnd.randn(M, N)

b = rnd.randn(N, K)

dot_1_t = repeat('dot_1(a, b)', repeat=1000, number=1, globals=globals())

dot_2_t = repeat('dot_2(a, b)', repeat=1000, number=1, globals=globals())

print(f'dot_1 took {median(dot_1_t)*1000} ms.')

print(f'dot_2 took {median(dot_2_t)*1000} ms.')

计时应与以下内容类似:dot_1 took 5.218300502747297 ms.

dot_2 took 0.013017997844144702 ms.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值