先写一个 dll
// Dll1.h
#ifndef PCH_H
#define PCH_H
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) int fib(int n);
__declspec(dllexport) int testfib(int value, int n);
#ifdef __cplusplus
}
#endif
#endif //PCH_H
// Dll1.c
#include "pch.h"
int fib(int n)
{
if (n <= 2)
return 1;
return fib(n - 1) + fib(n - 2);
}
int testfib(int value, int n)
{
int t = 0;
for (int i = 1; i < n + 1; i++)
// 加个条件判断,防止固定语句被编译器优化掉
if (i % 2)
t = fib(value + (i % 2));
else
t = fib(value + (i % 3));
return t;
}
用 Python 调用C函数
from ctypes import *
import time
def fib(n):
if n <= 2:
return 1
return fib(n - 1) + fib(n - 2)
def testfib(value, n):
t = 0
for i in range(1, n + 1):
if i % 2:
t = fib(value + (i % 2))
else:
t = fib(value + (i % 3))
return t
path = "./Dll1.dll"
num = 15
repeat = 500000
dll = cdll.LoadLibrary(path)
dll.fib.retype = c_int
dll.testfib.retype = c_int
# 调用 C 函数
st = time.time() * 1000
t = dll.testfib(num, repeat)
print("dll.testfib(): %.3f ms, final: %d" % (time.time() * 1000 - st, t))
# 循环调用 C 函数 fib(),实现与 testlib() 相同逻辑
st = time.time() * 1000
for i in range(1, repeat + 1):
if i % 2:
t = dll.fib(num + (i % 2))
else:
t = dll.fib(num + (i % 3))
print("dll.fib(): %.3f ms, final: %d" % (time.time() * 1000 - st, t))
# 纯 Python
st = time.time() * 1000
t = testfib(num, repeat)
print("Python: %.3f ms, final: %d" % (time.time() * 1000 - st, t))
Cython
%%cython -f
import time
cpdef int fib(int n):
if n <= 2:
return 1
return fib(n - 1) + fib(n - 2)
cpdef int testfib(int value, int n):
cdef int t = 0
cdef int i = 0
for i in range(1, n + 1):
# 加个条件判断,防止固定语句被优化掉
if i % 2:
t = fib(value + (i % 2))
else:
t = fib(value + (i % 3))
return t
st = time.time() * 1000
t = testfib(15, 500000)
print("cython: %.3f ms, final: %d" % (time.time() * 1000 - st, t))
环境
- Windows 7 x64
- i5-4590 3.30GHz
- 内存 16G
- VS2019
| 对比项 | 耗时 |
|---|
| C++调用C函数 testlib() | 1451 ms |
| Python直接调用C函数 testfib() | 1403.080 ms |
| Python循环调用C函数 fib() 实现 testfib() | 1723.099 ms |
| Cython | 1472.084 ms |
| 纯Python | 129531.409 ms |