你嫌弃Python 慢吗?这就是让它跑得更快的方法
你讨厌 Python 有多慢吗? 这就是让它跑得更快的方法


Python 是一种非常棒的编程语言,也是作者选择的语言。在我看来,Python 是最好的语言学习,因为你正在慢慢地打破你的方式进入计算机科学和编程的世界。
然而,每种编程语言都有它的优点和缺点,这就是为什么我们有这么多优点和缺点的原因。不同的用例需要不同的设计和实现。正如我们所说,没有放之四海而皆准的解决方案。
Python 是一种用户友好、易于学习、免费使用、可移植和易于扩展的编程语言。它适合您的编程风格和需求,涵盖了从面向对象(OOP)到函数式编程方法的各种风格。
另一方面,Python 是一个直译语言语言,它可以设置代码执行速度的上限。它不是非常适合移动开发,它有内存问题,而且由于它是一种动态类型语言,您可以在运行时发现大多数错误。
但并非所有的希望都已破灭。我认为,最关键的问题是速度。但是为什么更快的运行时间这么重要呢?考虑机器学习的用例; 您需要实验和快速迭代。在处理大数据时,让函数在几秒钟内返回,而不是几分钟内返回,是至关重要的。如果您刚刚发明的新的闪亮的神经网络架构不能很好地工作,您应该能够迅速转移到您的下一个想法!
为了解决这个问题,我们可以用另一种语言(例如,c 或 c + +)编写要求高的函数,并利用特定的绑定从 Python 调用这些函数。这是许多数字库(例如 NumPy、 SciPy 等)或深度学习框架(例如 TensorFlow、 PyTorch 等)在 Python 中所做的事情。所以,如果你是一个数据科学家或机器学习工程师想要调用 CUDA 功能,这个故事是为你。我们开始吧!
编组
在这个过程中,我们必须采取的第一步是理解什么是编组,以及它是如何工作的。来自维基百科:
编组是将对象的内存表示转换为适合存储或传输的数据格式的过程。
为什么这对我们的主题很重要?要将数据从 Python 转移到 c 或 c + + ,Python 绑定必须将其转换为适于传输的形式。
在 Python 中,一切都是一个对象。一个整数使用多少字节的内存取决于您所安装的 Python 的版本和您的操作系统,以及其他因素。另一方面,c 中的 uint8 _ t 整数总是使用8位的总内存。因此,我们必须以某种方式调和这两种类型。
编组是 Python 绑定为我们解决的问题,但是在某些情况下我们可能需要介入。这个故事不会是这样的,但是我们会在后面的文章中遇到。
管理内存
C 和 Python 管理内存的方式不同。在 Python 中,当声明一个对象时,Python 会自动为其分配内存。当您不需要该对象时,Python 有一个垃圾收集器,可以销毁未使用或未引用的对象,将内存释放回系统。
在 c 语言中,情况完全不同。是你,程序员,必须分配内存空间来创建一个对象,然后又是你,必须将内存释放回系统。
我们应该考虑到这一点,在语言障碍的同一侧释放不再需要的任何内存。
一个简单的例子
我们现在已经到了准备把脚浸入水中的时候了。完成本节后,您就可以开始使用 Python 绑定和 c 语言了。这绝对是一个初学者教程,但我们将在后面的故事中更深入地讨论更复杂的示例。
你需要什么
对于这个故事,我们需要两样东西:
- 3.6或更高版本
- Python 开发工具(例如 Python 3-dev 包)
C 源代码
为了简单起见,我们将创建并构建一个将两个数字相加的 c 库。复制下面的源代码:https://towardsdatascience.com/media/773f6c6255cbefe623b2fbf374e8ed43
接下来,我们需要编译源代码并构建一个共享库:
gcc -shared -Wl,-soname,libcadd -o libcadd.so -fPIC cadd.c
这个命令应该在你的工作目录文件夹中生成一个 libcadd.so 文件。现在你已经准备好进入下一步了。
使用 ctypes 打开 c 库
Ctypes 是 Python 标准库中创建 Python 绑定的工具。作为 Python 标准库的一部分,它非常适合我们的初学者教程,因为您不需要安装任何东西。
要从 Python 脚本中执行 c cadd 函数,请复制下面的源代码:https://towardsdatascience.com/media/277e7bca729f0dd6474e2a2448902fb8
在第7行中,我们创建了前面构建的 c 共享库的句柄。在第12行,我们声明 c cadd 函数的返回类型。这是至关重要的; 我们需要让 ctypes 知道如何对对象进行编组以传递它们,以及希望正确解组它们的类型。
第14行中的 y 变量也是如此。我们需要声明这是 float 类型的。最后,我们可以让 x 保持原样,因为默认情况下,ctypes 认为所有东西都是整数。
我们可以像执行其他 Python 脚本一样执行这个脚本:
python3 padd.py
结果就是一种魔法!
In cadd: int 6 float 2.3 returning 8.3
In Python: int: 6 float 2.3 return val 8.3
恭喜! 您已经从 Python 中调用了一个 c 库函数!
总结
Python 是一种用户友好、易于学习、免费使用、可移植和易于扩展的编程语言。
然而,它也有自己的弱点,其中最突出的就是速度。为了解决这个问题,我们可以用另一种语言(例如,c 或 c + +)编写要求高的函数,并利用特定的绑定从 Python 调用这些函数。
在本文中,我们使用了 ctypes,这是一个 Python 库,可以精确地做到这一点。我们可以从 Python 代码中调用一个 c 库并返回结果。我知道这个功能没有做任何要求,但这只是一个演示。让我们看看我们是否可以在以后的文章中做一些更具挑战性的事情!
原创文章,作者:flypython,如若转载,请注明出处:http://flypython.com/advanced-python/462.html
您必须登录才能发表评论。