为什么Python比FFI慢太多

huangapple go评论72阅读模式
英文:

Why Python is too slow compared to FFI

问题

以下是您要翻译的内容:

要说明性能差异,我比较了在纯Python中执行某个函数和在C中执行相同算法的函数的执行时间。首先,让我们测量纯Python中的执行时间:

def fibonacci(n: int):
    if n < 2:
        return 1

    return fibonacci(n - 2) + fibonacci(n - 1)

for _ in range(1000000):
    fibonacci(12)

执行时间:

$ /usr/bin/time nice python fibonacci.py
       29.66 real        29.52 user         0.06 sys

Python实现在循环中执行计算,总运行时间为29.66秒。那么使用FFI呢?让我们在C中编写一些简单的库代码:

int fibonacci(int n);

int fibonacci(int n) {
    if (n < 2) {
        return 1;
    }

    return fibonacci(n - 2) + fibonacci(n - 1);
}

然后让我们使用Python的ctypes模块从Python中调用这个函数,如下所示:

import ctypes

C = ctypes.cdll.LoadLibrary('./fibonacci.so')

C.fibonacci.argtypes = (ctypes.c_int,)
C.fibonacci.restype = ctypes.c_int

for _ in range(1000000):
    C.fibonacci(12)

执行结果:

$ /usr/bin/time nice python fibonacci-ffi.py
        1.09 real         1.01 user         0.01 sys

不错,1.09对比29.66 --- 快了29倍。但是,我有一些问题:

- Python实现中有哪些改进的空间可以弥合差距?
- 为什么执行时间差异如此显著?

[1]: https://docs.python.org/3/library/ctypes.html
英文:

To illustrate the performance difference, I compare the execution time of some function in pure Python and a function that executes the same algorithm implemented in C. First, let's measure the execution time in pure Python:

def fibonacci(n: int):
    if n &lt; 2:
        return 1
    
    return fibonacci(n - 2) + fibonacci(n - 1)

for _ in range(1000000):
    fibonacci(12)

Execution time:

$ /usr/bin/time nice python fibonacci.py
       29.66 real        29.52 user         0.06 sys

The Python implementation does the computation in a loop, with a total running time of 29.66 seconds. What about the FFI? Let's write some unsophisticated library code in C:

int fibonacci(int n);

int fibonacci(int n) {
    if (n &lt; 2) {
        return 1;
    }

    return fibonacci(n - 2) + fibonacci(n - 1);
}

And let's call this function from Python using the ctypes module, as follows:

import ctypes

C = ctypes.cdll.LoadLibrary(&#39;./fibonacci.so&#39;)

C.fibonacci.argtypes = (ctypes.c_int,)
C.fibonacci.restype = ctypes.c_int

for _ in range(1000000):
    C.fibonacci(12)

Execution result:

$ /usr/bin/time nice python fibonacci-ffi.py
        1.09 real         1.01 user         0.01 sys

Pretty good, 1.09 vs. 29.66 --- 29 times faster. However, I do have a few questions:

  • What can be improved in the Python implementation to bridge the gap?

  • Why is the execution time difference so significant?

答案1

得分: 1

如何改进Python实现以缩小差距?

您可以使用NumbaCythonPyPy来提高速度(Numba或PyPy可能更快,但有时需要修改代码)。

为什么执行时间差异如此显著?

如@freakish所提到的,Python是一种解释性、动态类型的语言,具有全局解释器锁(GIL),这使得它相对较慢。CPython(最流行的Python实现)也(与PyPy不同)没有JIT编译,但CPython在最近的未来之一的目标是提高Python的速度(从3.10版本开始,新的Python版本变得越来越快)。

英文:

> What can be improved in the Python implementation to bridge the gap?

You can use Numba, Cython or PyPy to improve speed (numba or pypy can be faster, but you sometimes need to modify code)

> Why is the execution time difference so significant?

As mentioned by @freakish, python is interpreted, dynamically typed language with GIL which leads it to be pretty slow. CPython (most popular python implementation) also (unlike PyPy) don't have JIT compilation, but one of cpython goals in the nearest future is to impove python speed (From 3.10 new python versions become faster and faster)

huangapple
  • 本文由 发表于 2023年3月15日 17:35:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75742851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定