说说故事

童话故事|儿童故事|谜语睡前故事|胎教故事|对联

资料学习

作文|范文|医学|留学|教程幼儿|考研|诗词|板报|名言

高考中考

高中|小学初中|大学

学科中心

语文|简谱|化学|政治|历史数学|生物|物理|地理|美术

考试学校

英语|题库|星座学校|高考|中考

用?Numba?加速?Python?代码,变得像?C++?一样快

目录

用?Numba?加速?Python?代码,变得像?C++?一样快

(给Python开发者加星标,提升Python技能)

?英文:Puneet?Grover,译:zxdefying,艾凌风?校稿?

整理:Python开发者(id:PythonCoder)

目录

    介绍

    为什么选择 Numba?

    Numba 是如何工作的?

    使用 Numba 的基本功能(只需要加上?@jit!)

    @vectorize 装饰器

    在 GPU 上运行函数

    扩展阅读

    参考

注意: 这篇文章的 Jupyter Notebook 代码在我的 Github 上:SpeedUpYourAlgorithms-Numba

1. 介绍

Numba 是 python 的即时(Just-in-time)编译器,即当您调用 python 函数时,您的全部或部分代码就会被转换为“即时”执行的机器码,它将以您的本地机器码速度运行!它由 Anaconda 公司赞助,并得到了许多其他组织的支持。

在 Numba 的帮助下,您可以加速所有计算负载比较大的 python 函数(例如循环)。它还支持 numpy 库!所以,您也可以在您的计算中使用 numpy,并加快整体计算,因为 python 中的循环非常慢。 您还可以使用 python 标准库中的 math 库的许多函数,如?sqrt?等。有关所有兼容函数的完整列表,请查看?此处。

2. 为什么选择 Numba?

那么,当有像?cython?和?Pypy?之类的许多其他编译器时,为什么要选择 numba?

原因很简单,这样您就不必离开写 python 代码的舒适区。是的,就是这样,您根本不需要为了获得一些的加速来改变您的代码,这与您从类似的具有类型定义的 cython 代码获得的加速相当。那不是很好吗?

您只需要添加一个熟悉的 python 功能,即添加一个包装器(一个装饰器)到您的函数上。类的装饰器也在开发中了。

所以,您只需要添加一个装饰器就可以了。例如:

from numba import jit@jitdef function(x): # your loop or numerically intensive computations return x

这仍然看起来像一个原生 python 代码,不是吗?

3. 如何使用 Numba?

“question mark neon signage” by?Emily Morter?on?Unsplash

Numba 使用?LLVM 编译器基础结构?将原生 python 代码转换成优化的机器码。使用 numba 运行代码的速度可与 C/C++ 或 Fortran 中的类似代码相媲美。

以下是代码的编译方式:

首先,Python 函数被传入,优化并转换为 numba 的中间表达,然后在类型推断(type inference)之后,就像 numpy 的类型推断(所以 python float 是一个 float64),它被转换为 LLVM 可解释代码。 然后将此代码提供给 LLVM 的即时编译器以生成机器码。

您可以根据需要在运行时或导入时?生成?机器码,导入需要在 CPU(默认)或?GPU?上进行。

4. 使用 numba 的基本功能(只需要加上 @jit !)

Photo by?Charles Etoroma?on?Unsplash

小菜一碟!

为了获得最佳性能,numba 实际上建议在您的 jit 装饰器中加上?nopython=True?参数,加上后就不会使用 Python 解释器了。或者您也可以使用?@njit。如果您加上?nopython=True的装饰器失败并报错,您可以用简单的?@jit?装饰器来编译您的部分代码,对于它能够编译的代码,将它们转换为函数,并编译成机器码。然后将其余部分代码提供给 python 解释器。

所以,您只需要这样做:

from numba import njit, jit@njit # or @jit(nopython=True)def function(a, b): # your loop or numerically intensive computations return result

当使用?@jit?时,请确保您的代码有 numba 可以编译的内容,比如包含库(numpy)和它支持的函数的计算密集型循环。否则它将不会编译任何东西,并且您的代码将比没有使用 numba 时更慢,因为存在 numba 内部代码检查的额外开销。

还有更好的一点是,numba 会对首次作为机器码使用后的函数进行缓存。 因此,在第一次使用之后它将更快,因为它不需要再次编译这些代码,如果您使用的是和之前相同的参数类型。

如果您的代码是?可并行化?的,您也可以传递?parallel=True?作为参数,但它必须与?nopython=True?一起使用,目前这只适用于CPU。

您还可以指定希望函数具有的函数签名,但是这样就不会对您提供的任何其他类型的参数进行编译。 例如:

from numba import jit, int32@jit(int32(int32, int32))def function(a, b): # your loop or numerically intensive computations return result# or if you haven"t imported type names# you can pass them as string@jit("int32(int32, int32)")def function(a, b): # your loop or numerically intensive computations return result

现在您的函数只能接收两个 int32 类型的参数并返回一个 int32 类型的值。 通过这种方式,您可以更好地控制您的函数。 如果需要,您甚至可以传递多个函数签名。

您还可以使用 numba 提供的其他装饰器:

    @vectorize:允许将标量参数作为 numpy 的 ufuncs 使用,

    @guvectorize:生成 NumPy 广义上的?ufuncs,

    @stencil:定义一个函数使其成为 stencil 类型操作的核函数

    @jitclass:用于 jit 类,

    @cfunc:声明一个函数用于本地回调(被C/C++等调用),

    @overload:注册您自己的函数实现,以便在?nopython?模式下使用,例如:?@overload(scipy.special.j0)

Numba 还有?Ahead of time(AOT)编译,它生成不依赖于 Numba 的已编译扩展模块。 但:

    它只允许常规函数(ufuncs 就不行),

    您必须指定函数签名。并且您只能指定一种签名,如果需要指定多个签名,需要使用不同的名字。

它还根据您的CPU架构系列生成通用代码。

5. @vectorize 装饰器

“gray solar panel lot” by?American Public Power Association?on?Unsplash

通过使用 @vectorize 装饰器,您可以对仅能对标量操作的函数进行转换,例如,如果您使用的是仅适用于标量的 python 的?math?库,则转换后就可以用于数组。 这提供了类似于 numpy 数组运算(ufuncs)的速度。 例如:

@vectorizedef func(a, b): # Some operation on scalars return result

您还可以将?target?参数传递给此装饰器,该装饰器使 target 参数为?parallel?时用于并行化代码,为?cuda?时用于在 cuda\GPU 上运行代码。

@vectorize(target="parallel")def func(a, b): # Some operation on scalars return result

使?target=“parallel”?或?“cuda”?进行矢量化通常比 numpy 实现的代码运行得更快,只要您的代码具有足够的计算密度或者数组足够大。如果不是,那么由于创建线程以及将元素分配到不同线程需要额外的开销,因此可能耗时更长。所以运算量应该足够大,才能获得明显的加速。

这个视频讲述了一个用 Numba 加速用于计算流体动力学的Navier Stokes方程的例子:

6. 在GPU上运行函数

“time-lapsed of street lights” by?Marc Sendra martorell?on?Unsplash

您也可以像装饰器一样传递 @jit 来运行 cuda/GPU 上的函数。 为此您必须从?numba?库中导入?cuda。 但是要在 GPU 上运行代码并不像之前那么容易。为了在 GPU 上的数百甚至数千个线程上运行函数,需要先做一些初始计算。 实际上,您必须声明并管理网格,块和线程的层次结构。这并不那么难。

要在GPU上执行函数,您必须定义一个叫做?核函数?或?设备函数?的函数。首先让我们来看?核函数。

关于核函数要记住一些要点:

a)核函数在被调用时要显式声明其线程层次结构,即块的数量和每块的线程数量。您可以编译一次核函数,然后用不同的块和网格大小多次调用它。

b)核函数没有返回值。因此,要么必须对原始数组进行更改,要么传递另一个数组来存储结果。为了计算标量,您必须传递单元素数组。

# Defining a kernel functionfrom numba import cuda@cuda.jitdef func(a, result): # Some cuda related computation, then # your computationally intensive code. # (Your answer is stored in "result")

因此,要启动核函数,您必须传入两个参数:

    每块的线程数,

    块的数量。

例如:

threadsperblock = 32blockspergrid = (array.size + (threadsperblock - 1)) // threadsperblockfunc[blockspergrid, threadsperblock](array)

每个线程中的核函数必须知道它在哪个线程中,以便了解它负责数组的哪些元素。Numba 只需调用一次即可轻松获得这些元素的位置。

@cuda.jitdef func(a, result): pos = cuda.grid(1) # For 1D array # x, y = cuda.grid(2) # For 2D array if pos < a.shape[0]: result[pos] = a[pos] * (some computation)

为了节省将 numpy 数组复制到指定设备,然后又将结果存储到 numpy 数组中所浪费的时间,Numba 提供了一些?函数?来声明并将数组送到指定设备,如:numba.cuda.device_arraynumba.cuda。 device_array_likenumba.cuda.to_device?等函数来节省不必要的复制到 cpu 的时间(除非必要)。

另一方面,设备函数?只能从设备内部(通过核函数或其他设备函数)调用。 比较好的一点是,您可以从?设备函数?中返

from numba import cuda@cuda.jit(device=True)def device_function(a, b): return a + b

您还应该在这里查看 Numba 的 cuda 库支持的功能。

Numba 在其 cuda 库中也有自己的?原子操作,随机数生成器,共享内存实现(以加快数据的访问)等功能。

ctypes/cffi/cython 的互用性:

cffi?– 在 nopython 模式下支持调用?CFFI?函数。

ctypes?– 在 nopython 模式下支持调用?ctypes?包装函数。

Cython 导出的函数是?可调用?的。

7. 扩展阅读

    https://nbviewer.jupyter.org/github/ContinuumIO/gtc2017-numba/tree/master/

    https://devblogs.nvidia.com/seven-things-numba/

    https://devblogs.nvidia.com/numba-python-cuda-acceleration/

    https://jakevdp.github.io/blog/2015/02/24/optimizing-python-with-numpy-and-numba/

    https://www.youtube.com/watch?v=1AwG0T4gaO0

8. 参考

    http://numba.pydata.org/numba-doc/latest/user/index.html

    https://github.com/ContinuumIO/gtc2018-numba

    http://stephanhoyer.com/2015/04/09/numba-vs-cython-how-to-choose/

谢谢阅读!

推荐阅读

(点击标题可跳转阅读)

8 个流行的 Python 可视化工具包,你喜欢哪个?

GitHub 热门:Python 算法大全,Star 超过 2 万

觉得本文对你有帮助?请分享给更多人

关注「Python开发者」加星标,提升Python技能

好文章,我在看??

Python开发者

赞赏

长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

用?Numba?加速?Python?代码,变得像?C++?一样快最新查阅>>
用?Numba?加速?Python?代码,变得像?C++?一样快相关:
发布时间:2019-07-12用?Numba?加速?Python?代码,变得像?C++?一样快

(给Python开发者加星标,提升Python技能)?英文:Puneet?Grover,译:zxdefying,艾凌风?校稿?整理:Python开发者(id:PythonCoder)目录介绍为什么选择 Numba?Numba 是如何工作的?使用 Numba 的基本功能(只需要加上?@jit!)@vectorize 装饰器在 GPU 上运行函数扩展阅读参考注..

发布时间:2019-07-11Phoenix自定义函数UDF异常解决方案

在Phoenix客户端使用自定义函数UDF时候是正常的,但是在本地测试的时候报Function类找不到的异常。异常演示例子@Test public void testSql2() throws SQLException { String sql = "select CRC32(\"userId\") from TEST_LOG"; ..

发布时间:2019-07-11Hbase - 自定义Rowkey规则

在Flink中我们有时候需要分析数据1点到2点的范围,可是经过Region又比较慢,这时候我们就可以定制TableInputFormat来实现我们的需求了,我们还可以采用Flink的DataSet的方式读取,另外下面还有Spark读取的例子。使用教程Md5Util.javaimport org.apache.commons.codec.binary.Hex..

发布时间:2019-07-11Hbase - 迁移数据[导出,导入]

有没有这样一样情况,把一个集群中的某个表导到另一个群集中,或者hbase的表结构发生了更改,但是数据还要,比如预分区没做,导致某台RegionServer很吃紧,Hbase的导出导出都可以很快的完成这些操作。环境使用现在环境上面有一张表logTable,有一个ext列簇但是没有做预分区,虽然可以强制拆分表,但是split的start,end范围无法精确控制..

发布时间:2019-07-11Hbase - 表导出CSV数据

新鲜文章,昨天刚经过线上验证过的,使用它导出了3亿的用户数据出来,花了半个小时,性能还是稳稳的,好了不吹牛皮了,直接上代码吧。MR考查了Hbase的各种MR,没有发现哪一个是能实现的,如果有请通知我,我给他发红包。所以我们只能自己来写一个MR了,编写一个Hbase的MR,官方文档上也有相应的例子。我们用来加以化妆就得到我们想要的了。导出的CSV格式为adm..

发布时间:2019-07-11Thursday

??赞赏长按二维码向我转账受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

发布时间:2019-07-11国货=没卵用?用完脸比脖子白一个色号,这些国货pick一下!

/?星标关注满满cyim·每天有惊喜?/不得不说,很多仙女都特别迷恋实验室研发的护肤品,原因很简单——安全感!连近来的国货也刮起了一股新派实验室风,颜值和效果都颠覆大家传统印象。有人说,甲之蜜糖乙之砒霜,选护肤品的第一守则是适合自己。怎么才能证明一款护肤品适合自己呢?唯有一个字:试。尝遍百草后我发现,实验室品牌基本上90%都很安全。既可以满足了很多人的「?..

发布时间:2019-07-11一件内衣hold住所有夏装,后悔现在才知道!

大家好!我是对龙虾过敏的鲨鱼姐?? 不 露 肩? ?不 夏 天毕竟,露胸最色情,不露痕迹的展示我们纤长的天鹅颈、迷人的锁骨弱不禁风的美背……才是大写的性感又到了吊带衫,露背装性感连衣裙,穿起来的季节啦!但一想到里面应该穿什么样的内衣合适,很多仙女应该都有些头疼吧?内衣没选好再漂亮的衣服都能引来尴尬!穿吊带的时候露出肩带?坦白讲还不如不穿!尤其是肩带颜色和吊..

发布时间:2019-07-10失信被执行人与限制高消费令一样吗

失信被执行人与限制高消费令是不一样。只要被列入失信执行人,那么就不可以进行高消费,飞机高铁和星级的酒店都是不可以乘坐和居住的。更不用说什么贷款,不过可以进行解除,可以到人民法院咨询一下具体的解除方式。一、失信被执行人与限制高消费令一样吗不一样的,失信被执行人俗称“老赖”,被列入全国失信被执行人名单,就相当于向全社会宣布这个人是不诚信的“老赖”。作为失信被执..

发布时间:2019-07-09WNBA康涅狄克太阳VS亚特兰大梦想

时间:6月10日 3:00亚特兰大梦想目前在常规赛3战仅取得了1胜2负,球队的成绩较差,亚特兰大梦想在首战击败了飞翼,但球队随即连续输给了风暴和奇异,亚特兰大梦想得分能力太差,球队本赛季场均得分仅有72分,亚特兰大梦想没有任何一名球员场均可以得到超过11分,球队的得分能力在联盟排名倒数。康涅狄..

发布时间:2019-07-09读书和不读书,过的是不一样的人生

锻炼与不锻炼的人,隔一天看,没有任何区别;隔一个月看,差异甚微;但是隔五年十年看,身体和精神状态上就有了巨大差别。读书也是一样的道理,读书与不读书的人,日积月累,终成天渊之别。今天多学一点知识,明天就少一句求人的话。问:“我读过很多书,但后来大部分都忘记了,你说这样的阅读究竟有什么意义?”答:“当我还是个孩子时,我吃过很多食物,现在已经记不起来吃过什么了。..

发布时间:2019-07-09Hbase BulkLoad用法

新鲜文章,昨天刚经过线上验证过的,使用它导出了3亿的用户数据出来,花了半个小时,性能还是稳稳的,好了不吹牛皮了,直接上代码吧。MR考查了Hbase的各种MR,没有发现哪一个是能实现的,如果有请通知我,我给他发红包。所以我们只能自己来写一个MR了,编写一个Hbase的MR,官方文档上也有相应的例子。我们用来加以化妆就得到我们想要的了。导出的CSV格式为adm..

发布时间:2019-07-09Logstash - JSON格式文件转换

一份简单可用的JSON转换配置test.log{"time":1526659044,"data":"{\"appKey\":\"7b9a2890-5754-11e8-983c-6b4bcc3b7c2e\",\"channelCode\":\"\",\"channelId\":\"\",\"createDateTime\":1526659043119,\"p..

发布时间:2019-07-08MONDAY

时尚家居// 你可能喜欢 //??一个阳台半个家,秀一波初夏浪漫操作~20㎡日式混搭小公寓丨以最喜欢的方式与自己相处温柔轻简的小家,通透隔墙让阳光洒进每个角落长按二维码添加订阅TRENDSHOME▼

发布时间:2019-07-07我们不一样

练太极拳真的可以让自己的心静下来,并且脾气越来越平和,专注与自己对话,不要失信于自己,记住对自己的承诺。扛过去自己现在的不穷不富的日子,记住,答应自己的事一定要做到。图片发自51Ui.cnApp如果你自己活得不够好,就会有人跑来告诉你,你之所以今天过得不好,就是因为和他们不一样。他们会说你傻,说你另类,劝你不要再搞特殊化,赶紧加入他们的队伍,做和大家一样的..

发布时间:2019-07-06“兼顾3个公司3个娃,40岁前财务自由”?|?但其实她的起点和你一样

我一直很奇怪一件事情,特别是我30岁之后。20多岁的时候,人人都上班,作为普通人,大家过得都差不多。可过了30岁,好像突然就“分流”了。有的人人突然一飞冲天,大house、移民、海外置业、全球旅行成了最常见的话题,出入私立医院和私立学校都是生活的常态。还有名牌衣服包包鞋子,这些随随便便动辄几万的消费完全不在话下。?还有很多人不上班了,天天做点自己喜欢的事儿..

发布时间:2019-07-06200行2列,变40行10列,呀呼嘿,你哪里想得到?

A和B列有200行要变成右边的40行10列的造型请问怎么办?当然函数啦!!!D1写公式,一步到位搞定=OFFSET($A$1,ROW(1:1)-1+40*(ROUNDUP(COLUMN(A$1)/2,0)-1),MOD(COLUMN(A$1)-1,2))具体解释忽略要学习直接听我课程里的讲解《520节=Excel+PPT+Word小白变高手》学office..

发布时间:2019-07-06Happy?Weekend!?周末快乐!

音乐资源加载中...Introductory Reading 本期导读①.?Exhibition:Private Talent 展览:才华独有②.?An Amazing Culinary Journey of Le Petit Chef 中国大饭店小厨师马可波罗奇幻美食之旅③.?Music 音乐&戏剧④.?Wise Words?每日佳句About Us ?..

发布时间:2019-07-06朱光潜:像个大人一样生存,像个孩子一样生活

朱光潜:《像个孩子:谈美》人生是多方面而却相互和谐的整体,把它分析开来看,我们说某部分是实用的活动,某部分是科学的活动,某部分是美感的活动,为正名析理起见,原应有此分别;但是我们不要忘记,完满的人生见于这三种活动的平均发展,它们虽是可分别的却不是互相冲突的。“实际人生”比整个人生的意义较为狭窄。一般人的错误在把它们认为相等,以为艺术对于“实际人生”既是隔着..

发布时间:2019-07-06今天不一样

今天不一样,是因为我早起了,昨夜睡眠不佳,许是运动过度?或是己休息够多?不得知,原本以为昨天中午不曾午睡,又走了大量的路,还泡了脚,我可以一夜安睡呢,结果却是倦而睡不着,小妞超出我预期的晚睡,让我有些心烦,在将睡未睡时,夫君的咳嗽又将我的瞌睡虫驱走,更是心烦,以前尝试的腹式呼吸因心不静而未能发挥功用,反反复复的心烦也不知何时才睡去,然后晚上睡得也不安稳,各..

百度用?Numba?加速?Python?代码,变得像?C++?一样快:

栏目推荐
热点排行
推荐阅读