python shape函数_Perlin噪声和Python的ctypes

f9ff8752bcfc26824e35f62124c3c106.png

最近在知乎上看了一篇关于用C++加速Python的短文,受益匪浅。同时也受到启发,撰写此文作为以后的参考。

作为Python的用户经常碰到的一个问题就是速度太慢,一般来说速度下降的一个主要原因是来自多重的for循环。如何给现有的Python代码加速其实是Python用户的一门必修课。比较熟悉numpy的用户,可以熟练地写成矩阵化操作,这样可以大大加速运行的效率。这和MATLAB里多用矩阵操作而少用for循环是一个道理。但往往我们中的大多数并没有高超的numpy技巧。即便是有,Python代码的阅读性可能反而会下降。就算退一步讲,写成了比较好的numpy的代码也未必会比C/C++的代码快。在不放弃Python语言的前提下,怎么用C语言来提速呢?方法有很多,前面的所指的短文已经给出了一个答案。这里我再用一个例子做一个简单的说明,希望对大家有所帮助。首先代码都可以取到,

https://github.com/yanfeit/PerlinNoise​github.com

关于Perlin噪声,我就不详细介绍。简单地说来,Perlin噪声具有光滑性,自然性和随机性的特点。感兴趣的读者可以找到很多相关资料,在这里我推荐两个,pvigier的GitHub site和Adrian's 的博客。Pvigier的Perlin噪声是用numpy来实现的,读者如果对自己numpy的技巧深感自信,可以去阅读一下他写的代码。阅读他的代码之后,我们可以给自己两个问题:

  1. 我是否可以写出这样高度矩阵化操作的numpy代码?
  2. 是否我们遇到的所用问题都可以用numpy矩阵化的操作来解决?

我想读者心中可能也会犯嘀咕,确实,高度矩阵化的操作需要程序员有高超的numpy技巧。反正我自愧不如,认为我很难写出那样漂亮的代码。我们再来看看Adrian的博客,这是篇博客文中的上乘之作, 是关于Perlin噪声的一个详细介绍,配合C#来实现。我想大多数读者可能和我一样,对写成for循环的形式感到极度舒适。而阅读这样的代码我想读者们也是驾轻就熟吧。所以我首先制作了一个Perlin噪声的C++代码(其实只用到了C的成分),之后我们会使用ctypes来调用动态链接库的代码。

创建动态链接库

cd build
$ cmake ..
$ make
$ mv ./lib/libperlinNoise.dylib ../python 

为了快速测试一下效果,读者可以尝试执行以上的代码。

用了make之后我们会在/build/lib目录下得到一个libperlinNoise.dylib的动态链接库文件,在这个库里面我们可以调用两个函数。它们的接口如下所示,

// 你可以在./lib/PerlinNoise.h的文件中找到相应代码。

两个函数返回的是指向Float的指针,我选用了单精度的浮点数也就是float。这里面有个需要注意的地方,函数切记不要返回指向一个超过二维数组的指针,其实根本就没有这样的定义,具体请看这个帖子。有了libperlinNoise.dylib这个动态链接库之后,剩下的任务就交给Python了。以下是我的代码的一部分(借鉴了Pvigier的代码,在./python/cppnoise.py中可以找到相应的代码),

# 我们所采用加速的方法,ctypes是build-in package

相比于木盏的函数,我这里相对来说复杂一点点。我们需要注意的是,我们得告诉函数传入的参数的类型和返回的类型和大小,这点至关重要。

# 读取动态链接库,

在Python中调用动态链接库后得到的加速效果(当然我在C++用了单精度的float),读者可以自行修改成双精度去测试一下。

$ python caltime.py
2D noise, numpy time consuming:  0.08261830806732177
3D noise, numpy time consuming:  4.525643992424011
2D noise, cpp time consuming:  0.007184123992919922
3D noise, cpp time consuming:  0.1645211935043335

我们可以发现C语言的代码可以说快了将近10倍以上。


最后上个图,以飨读者。

eb2f44ef428187b6b7f63d1f91fbf51e.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值