c函数返回从python调用的double类型的错误输出



我想加快python代码调用c函数的速度:

我有一个香草pythonsum_and_multiply.py的函数:

def sam_py(lim_sup):
total = 0
for i in range(0,lim_sup): # xrange is slower according 
for j in range(1, lim_sup):            #to my test but more memory-friendly.
total += (i / j)
return total

则在Csum_and_multiply_c.c中有等价函数:

#include <stdio.h>

double sam_c(int lim_sup){
int i;
int j;
double total;
total = 0;
double div;
for (i=0; i<lim_sup; i++){
for (j=1; j<lim_sup; j++){
div = (double) i / j;
//      printf("div: %.2fn", div);
total += div;
//     printf("total: %.2fn", total);
}
}
printf("total: %.2fn", total);
return total;
}

一个文件script.py,它调用两个函数

from sum_and_multiply import sam_py
import time
lim_sup = 6000
start = time.time()
print(sam_py(lim_sup))
end = time.time()
time_elapsed01 = end - start
print("time elapsed: %.4fs" % time_elapsed01)
from ctypes import *
my_c_fun = CDLL("sum_and_multiply_c.so")
start = time.time()
print(my_c_fun.sam_c(lim_sup))
end = time.time()
time_elapsed02 = end - start
print("time elapsed: %.4fs" % time_elapsed02)
print("Speedup coefficient: %.2fx" % (time_elapsed01/time_elapsed02))
最后是一个shell脚本bashscript.zsh,它编译C代码,然后调用script.py
cc -fPIC -shared -o sum_and_multiply_c.so sum_and_multiply_c.c
python script.py

输出如下:

166951817.45311993
time elapsed: 2.3095s
total: 166951817.45
20
time elapsed: 0.3016s
Speedup coefficient: 7.66x

这是我的问题,虽然c函数正确计算结果(通过printf输出166951817.45),但它传递给python时的输出是20,这是错误的。怎么可能是166951817.45呢?

编辑更改script.py的最后一部分后问题仍然存在,如下所示:

from ctypes import *
my_c_fun = CDLL("sum_and_multiply_c.so")
my_c_fun.restype = c_double
my_c_fun.argtypes = [ c_int ]
start = time.time()
print(my_c_fun.sam_c(lim_sup))
end = time.time()
time_elapsed02 = end - start
print("time elapsed: %.4fs" % time_elapsed02)
print("Speedup coefficient: %.2fx" % (time_elapsed01/time_elapsed02))

你假设Python可以"看到";你的函数返回一个double。但它不能。C不"编码"。任何东西的返回类型,所以从库中调用函数的人都需要知道它的返回类型,否则就有可能误解它。

你应该在使用CDLL之前阅读它的文档!如果您说这是为了练习,那么这个练习需要包括阅读文档(这是优秀的程序员所做的,没有借口)。

class ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

该类的实例表示加载的共享库。这些库中的函数使用标准的C调用约定,并假定返回int

(我强调。)

https://docs.python.org/2.7/library/ctypes.html#return-types是你的朋友(页面的顶部会告诉你Python2已经死了,你不应该使用它,即使你坚持使用它。)我相信你有比Python开发者自己更好的理由!)。

my_c_fun = CDLL("sum_and_multiply_c.so")
sam_c = my_c_fun.sam_c
sam_c.restype = c_double
sam_c.argtypes = [ c_int ]
value = sam_c(6000)
print(value)

是正确的选择。

相关内容

  • 没有找到相关文章