Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么在Python中使用numpy进行矩阵乘法要比使用ctype快?

为什么在Python中使用numpy进行矩阵乘法要比使用ctype快?
EN

Stack Overflow用户
提问于 2012-05-04 03:36:22
回答 5查看 33.4K关注 0票数 58

我试图找出做矩阵乘法的最快方法,并尝试了3种不同的方法:

纯python实现:这里没什么好奇怪的。

使用numpy.dot(a,b)实现Numpy

使用Python语言中的ctypes模块与C进行接口。

这是转换为共享库的C代码:

以及调用它的Python代码:

我敢打赌,使用C语言的版本会更快……我就输了!下面是我的基准测试,它似乎表明我做得不正确,或者numpy的速度非常快:

我想要理解为什么numpy版本比ctypes版本更快,我甚至不是在谈论纯粹的Python实现,因为它是很明显的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-05-04 05:01:05

我对Numpy不是很熟悉,但它的源码在Github上。部分点积是用https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/arraytypes.c.src,实现的,我假设它被转换成每种数据类型的特定C实现。例如:

这似乎是在计算一维点积,即对向量进行计算。在我浏览Github的几分钟内,我无法找到矩阵的源代码,但它可能会对结果矩阵中的每个元素使用一次对FLOAT_dot的调用。这意味着这个函数中的循环对应于最里面的循环。

它们之间的一个区别是“步幅”-输入中连续元素之间的差异-在调用函数之前显式计算一次。在你的例子中没有步幅,每次输入的偏移量都是计算出来的,例如a[i *n+ k]。我曾期望一个好的编译器能将它优化成类似于Numpy stride的东西,但它可能无法证明步长是一个常数(或者它没有被优化)。

Numpy也可能在调用此函数的高级代码中使用缓存效果做一些聪明的事情。一个常见的技巧是考虑每一行是连续的,还是每一列都是连续的--并尝试首先迭代每个连续的部分。似乎很难做到完美的优化,对于每个点积,一个输入矩阵必须按行遍历,另一个按列遍历(除非它们碰巧以不同的主序存储)。但它至少可以为result元素做到这一点。

Numpy还包含代码,用于从不同的基本实现中选择特定操作的实现,包括“点”。例如,它可以使用BLAS库。从上面的讨论看,似乎使用了CBLAS。这是从Fortran翻译成C的。我认为你的测试中使用的实现应该是在这里找到的: http://www.netlib.org/clapack/cblas/sdot.c.

请注意,此程序是由一台机器编写的,以供另一台机器读取。但您可以在底部看到,它使用一个展开的循环一次处理5个元素:

这个展开因子很可能是在分析了几个之后选择的。但它的一个理论优势是在每个分支点之间进行更多的算术操作,编译器和CPU有更多的选择来优化它们,以获得尽可能多的指令流水线。

票数 28
EN

Stack Overflow用户

发布于 2012-08-20 02:48:42

NumPy使用高度优化、精心调整的BLAS方法进行矩阵乘法(另请参阅: ATLAS)。本例中的特定函数是GEMM (用于通用矩阵乘法)。你可以通过搜索dgemm.f (它在Netlib中)来查找原文。

顺便说一句,优化超越了编译器优化。上面,Philip提到了Coppersmith-Winograd。如果我没记错的话,这是ATLAS中大多数矩阵乘法使用的算法(尽管有评论者指出它可能是Strassen的算法)。

换句话说,您的matmult算法是微不足道的实现。有更快的方法来做同样的事情。

票数 34
EN

Stack Overflow用户

发布于 2012-05-04 06:30:49

用来实现某种功能的语言本身就不能很好地衡量性能。通常,使用更合适的算法是决定性因素。

在您的例子中,您使用的是学校教授的简单的矩阵乘法,它在O(n^3)中。然而,对于某些类型的矩阵,你可以做得更好,例如方阵,备用矩阵等等。

看看Coppersmith-Winograd算法(O(n^2.3737)中的方阵乘法),作为快速矩阵乘法的良好起点。另请参阅“参考”一节,其中列出了一些指向更快方法的指针。

有关惊人性能提升的更真实示例,请尝试编写一个fast strlen(),并将其与glibc实现进行比较。如果你不能击败它,请阅读glibc的strlen()源代码,它有相当不错的评论。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10442365

复制
相关文章
sqlzoo练习8-self-join
This is a list of areas served by buses. The detail does not really include each actual bus stop - just areas within Edinburgh and whole towns near Edinburgh.
皮大大
2021/03/02
3680
SQL JOIN
在机房收费系统个人重构的时候,很多的功能都需要根据数据库中的一个表中的信息,去查询另一个表中相匹配的信息,我们用到了视图,但是你有没有注意到下面的SQL语句呢?(SELECT...FROM...JOIN...ON...),接下来我们就一起来了解SQL中的JOIN.
令仔很忙
2018/09/14
7920
SQL JOIN
如何在 SQL 中使用 LEFT、RIGHT、INNER、OUTER、FULL 和 SELF JOIN?
在进行复杂的分析处理和数据发现时,一个表的数据通常不足以提供重要的见解,因此需要合并多个表。 SQL,作为与关系数据库通信的一种方法,允许您在表之间创建关系.
从大数据到人工智能
2022/03/22
2.1K0
如何在 SQL 中使用 LEFT、RIGHT、INNER、OUTER、FULL 和 SELF JOIN?
sql中left join、right join、inner join区别
aID aNum 1     a0111 2     a0112 3     a0113 4     a0114 5     a0115
csxiaoyao
2019/02/18
1.8K0
SQL基础【十五、join、Inner join、Left join、Right join、Full join】
数据库中的表可以通过键将彼此联系起来,主键是一个列,在这个列中的每一行的值都是唯一的,在表中,每个主键的值都是唯一的,这样就可以在不重复每个表中的所有数据的情况下,把表间的数据交叉捆绑在一起。
红目香薰
2022/11/28
1.6K0
Spark SQL JOIN
本文主要介绍 Spark SQL 的多表连接,需要预先准备测试数据。分别创建员工和部门的 Datafame,并注册为临时视图,代码如下:
每天进步一点点
2022/07/27
7910
Spark SQL JOIN
sql连接查询(inner join、full join、left join、 right join)
需求:查询哪个顾客(customer_name)在哪一天(create_time)消费了多少钱(money)
用户2409797
2018/08/30
5.7K0
sql连接查询(inner join、full join、left join、 right join)
sql之left join、right join、inner join的区别
Please refer the link : https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
Hongten
2018/09/13
1.7K0
sql之left join、right join、inner join的区别
Flink join终结者:SQL Join
SQL是开发人员与数据分析师必备的技能,Flink也提供了Sql方式编写任务,能够很大程度降低开发运维成本,这篇是flink join的终极篇SQL Join, 首先介绍sql join使用方式、然后介绍global join带来的状态存储成本及解决方式、最后从源码角度分析sql join实现。
Flink实战剖析
2022/04/18
8770
sql之left join、right join、inner join的区别
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 inner join(等值连接) 只返回两个表中联结字段相等的行 举例如下: -------------------------------------------- 表A记录如下: aID     aNum 1     a20050111 2     a20050112 3     a20050113 4     a20050114 5 
学到老
2018/03/16
1.5K0
sql之left join、right join、inner join的区别
举例如下: -------------------------------------------- 表A记录如下: aID     aNum 1     a20050111 2     a20050112 3     a20050113 4     a20050114 5     a20050115
学到老
2019/02/13
2K0
sql LEFT JOIN RIGHT JOIN(左连接)(mysql)
在这里,LEFT JOIN(内连接,或等值连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。 例如,如果table2中的age1的值有一个值是11,table1的值中age1的值也有11,那么就查询出来;但是table2中如果有值2134,table1中的age1并不存在2134,那么这个值就不会查询出来: 再假设,如果table1中有age1的值2,3,4但是table2中没有一个age1的值是2,3,4那么table1中就会显示出来2,3,4;换句话说,使用left join,最开始的表,左表会全部显示出来,右表则会显示左表中有的值。
1_bit
2021/01/14
1.9K0
sql LEFT JOIN RIGHT JOIN(左连接)(mysql)
SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
  今天主要的内容是要讲解SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别和用法,不用我说其实前面的这些基本SQL语法各位攻城狮基本上都用过。但是往往我们可能用的比较多的也就是左右连接和内连接了,而且对于许多初学者而言不知道什么时候该用哪种语法进行查询,并且对于左右,或者内连接查询的时候关于ON 和Where 的作用也是模糊不清的,说不出其中的一个大概的差别,因此接下来请容我把它们好好描述一遍。
追逐时光者
2019/08/28
9.4K1
SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
sql之left join、right join、inner join的区别
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
PM吃瓜
2019/08/12
1.2K0
sql之left join、right join、inner join的区别
SQL 连接(JOIN)专题
SQL 最强大的功能之一就是能在数据检索查询的执行中联结(join)表。联结是利用 SQL 的 SELECT 能执行的最重要的操作,很好地理解联结及其语法是学习SQL的一个极为重要的组成部分。另外聚集函数也可以在联结中进行使用。
acc8226
2022/05/17
2K0
SQL 连接(JOIN)专题
图解SQL的Join
对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。
码农编程进阶笔记
2021/07/20
6060
图解SQL的Join
SQL命令 JOIN(二)
使用标准的“inner”联接时,当一个表的行链接到第二个表的行时,第一个表中找不到第二个表中对应行的行将从输出表中排除。
用户7741497
2022/05/06
1.6K0
SQL命令 JOIN(一)
(上述联接语法用于SELECT语句FROM子句。可以在其他SELECT语句子句中使用其他联接语法。)
用户7741497
2022/05/06
2.2K0
图解SQL的Join
对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。
全栈程序员站长
2022/07/19
3500
图解SQL的Join
sql语法:inner join on, left join on, right join on具体用法
right join(右联接) 返回包含右表中的全部记录和左表中联结字段相等的记录
全栈程序员站长
2022/07/14
1.5K0

相似问题

SQL Self Join wo主键

13

SQL Self Left Join挑战

30

SQL Sum和self join?

32

最新行的SQL - Self join

20

Sybase SQL update with self-join

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文