返回从 python 调用的 double 的 c 函数的错误输出
Wrong ouptut of a c function returning a double called from python
我想加快 python 代码调用 c 函数的速度:
我有原版的功能 python sum_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
然后我在 C 中有等效的函数 sum_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: %.2f\n", div);
total += div;
// printf("total: %.2f\n", total);
}
}
printf("total: %.2f\n", total);
return total;
}
一个文件script.py
,它调用了 2 个函数
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 可以“看到”您的函数 return 是 double
。但它不能。 C 不会对 return 类型进行任何“编码”,因此从库中调用函数的任何人都需要知道它的 return 类型,否则就有可能误解它。
你应该在使用前阅读 CDLL
的文档!如果你说这是为了锻炼,那么这个锻炼就需要包括阅读文档(这就是优秀的程序员所做的,没有任何借口)。
class ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)
Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return 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)
是必经之路。
我想加快 python 代码调用 c 函数的速度:
我有原版的功能 python sum_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
然后我在 C 中有等效的函数 sum_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: %.2f\n", div);
total += div;
// printf("total: %.2f\n", total);
}
}
printf("total: %.2f\n", total);
return total;
}
一个文件script.py
,它调用了 2 个函数
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 可以“看到”您的函数 return 是 double
。但它不能。 C 不会对 return 类型进行任何“编码”,因此从库中调用函数的任何人都需要知道它的 return 类型,否则就有可能误解它。
你应该在使用前阅读 CDLL
的文档!如果你说这是为了锻炼,那么这个锻炼就需要包括阅读文档(这就是优秀的程序员所做的,没有任何借口)。
class ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)
Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return
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)
是必经之路。