最近在知乎上看了一篇关于用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倍以上。


最后上个图,以飨读者。

python shape函数_Perlin噪声和Python的ctypes相关推荐

  1. python 定义函数方法,python中函数如何定义?python函数的调用方法介绍

    本篇文章给大家带来的内容是关于python中函数如何定义?python函数的调用方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1. 函数的概念,函数是将具有独立功能的代码块 ...

  2. python while函数_详解python while 函数及while和for的区别

    1.while循环(只有在条件表达式成立的时候才会进入while循环) while 条件表达式: pass while 条件表达式: pass else: pass 不知道循环次数,但确定循环条件的时 ...

  3. python编写函数_浅谈Python 函数式编程

    匿名函数lambda表达式 什么是匿名函数? 匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑.lambda 本质上是一个 ...

  4. python len函数_知识清单Python必备的69个函数,你掌握了吗?

    本文纲要 Python 作为一门高级编程语言,为我们提供了许多方便易用的内置函数,节省了不少开发应用的时间.目前,Python 3.7 共有 69 个内置函数,一些是我们耳熟能详的函数,另一些却不是很 ...

  5. python编写函数_如何用Python编写自己喜欢的R函数

    python编写函数 数据科学和机器学习的伟大现代斗争之一是" Python vs. R". 毫无疑问,近年来两者都已经取得了巨大的发展,成为数据科学,预测分析和机器学习的顶级编程 ...

  6. python toimage函数 -baijiahao_财码Python管理会计小实验成本性态分析So Easy

    欢迎来到财码Python管理会计小实验系列课程,今天是小实验系列的首篇--成本性态分析. 用Python,So Easy~~  话不多说,直接入题--管理会计知识点回顾成本性态,是指成本与业务量之间的 ...

  7. python zip函数_相当于Python的zip函数

    下面是一个更时髦的ECMAScript 6版本:zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c])) 插图等价物到Python{z ...

  8. python quit函数作用_初识Python之基础知识

    安装了Anaconda3以及Jupyter notebook后对Python中的一些基础语法.定义容器,对容器做增删改,定义及调用函数做了学习,并且在notebook中实践敲了代码 数据类型:字符串( ...

  9. python向函数传递列表,【Python】向函数传递列表

    向函数传递列表 在实际使用中你会发现,向函数传递列表是比较实用的,这种列表可能包含名字.数字.可能更复杂的对象(字典) 假设向一个函数传递一堆水果,我们说出我们喜欢所有的水果 def Obj(frui ...

最新文章

  1. python beautifulsoup模拟点击_Python爬虫丨BeautifulSoup实践
  2. elegance suites bangkok info
  3. 【微信小程序企业级开发教程】微信小程序目录结构
  4. python中两个矩阵之间的点乘_Python基础--数据分析库--Numpy
  5. Spring 执行 sql 脚本(文件)
  6. 【转】请让孩子输在起跑线上
  7. 记一次ElasticSearch重启之后shard未分配问题的解决
  8. Android开发,使用背景图(xml drawable)为view 设置边框
  9. html js 回调函数,js中回调函数的学习笔记
  10. 对话李飞飞:云数据库战争已经进入下半场
  11. Java中如何编写一个完美的equals方法
  12. 苹果下半年推出M2芯片MacBook Air 配色更多更轻薄
  13. linux java缓存失效_转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案...
  14. python基础:sys模块
  15. 第九届蓝桥杯C/C++ 大学B组省赛编程题题目及答案解析
  16. 概率论 方差公式_概率论学习笔记(6)
  17. python求一个数所有因数
  18. python人工智能之:多边形矩阵热图程序实战篇(二)
  19. Vue使用echarts报错提示 vue.runtime.esm.js?2b0e:1897 Error: Initialize failed: invalid dom.
  20. 什么是Teardrop攻击

热门文章

  1. php 创建 cookie文件,PHP创建Cookie数组
  2. 深入理解Java虚拟机-常用vm参数分析
  3. 对不起,我就是喜欢问你Spring构造器注入原理
  4. Java8 HashMap详解
  5. svn教程----权限管理
  6. Git和Github简单教程
  7. 2021- 10 -9 LeetCode 958. 二叉树的完全性检验(待补完)
  8. 【深入Java虚拟机JVM 01】Java发展与展望概述
  9. 前端面试中常见的算法问题
  10. Ajax+jquery实现异步验证用户名功能