现阶段很多网站都是基于非编译的语言,例如Php,Python语言完成。这样做的效果是开发效率很高,同时开发人员也很容易就位。当网站访问量达到一个数量级之后,就会遇到传说中的C10K问题,借助解释型语言的性能劣势,整个网站会到达一种“无处修改,无处优化,无处升级”的怪圈。这时候往往就会需要采用更加底层的C去重构部分或整个项目,“C重构”由此而来。当然,技术的进化也很迅速,FaceBook开源了hiphop这个PHP2C的工具,可以部分自动化的实现“C重构”。
一直把Python当成胶水语言来用,这次就接着这个话题,说个Python C重构的例子:
首先是python原码:(很眼熟吗?)
#!/usr/bin/env python
import time
lGoal = {}
def main(i):
# if lGoal.has_key(i):
# return lGoal[i]
if i < 1:
return long (0)
elif i < 2:
return long(1)
return main(i-1) + main(i-2) - main(i-5)
def getList(iMax):
for i in range(1, iMax+1):
iGoal = main(i)
lGoal[i] = iGoal
return lGoal
#i = int(raw_input())
i = 30
timeStart = time.time()
getList(i)
print "Cost: %s" % (time.time() - timeStart)
看看它的耗时:
Cost: 21.9739699364
首先对于这种多重循环和调用,绝对是C的强项,理论上Python 2 C 之后会有很大的提升空间。重构的思路是用Python的ctypes模块调用基于C的lib库,这样可以在保留大部分Python代码的基础上完成重构,而且重构之后的程序仍然还是Python的。
开始C重构vi LoadTest.c:
#include <stdio.h>
/*
int main()
{
int i, goal;
for (i=1; i <= 30; i++)
{
goal = C_Time_Cost(i);
printf ("%d, %d n", i, goal);
}
return 0;
}
*/
int C_Time_Cost(int a)
{
if (a < 1)
{
return 0;
}
if (a < 2 )
{
return 1;
}
return C_Time_Cost( a - 1 ) + C_Time_Cost( a - 2 ) - C_Time_Cost( a - 5 ) ;
}
编译到.o文件:
gcc -c LoadTest.c -fPIC
编译成为Lib
gcc –shared -o libLoadTest.so LoadTest.o
cp libLoadTest.so /lib64 && ldconfig //这一点很重要,否则会报找不到lib文件。
修改python:
#!/usr/bin/env python
import time
from ctypes import *
lGoal = {}
def main(i):
cdll.LoadLibrary("libLoadTest.so")
libc = CDLL("libLoadTest.so")
goal = libc.C_Time_Cost(c_int(i))
return goal
def getList(iMax):
for i in range(1, iMax+1):
iGoal = main(i)
lGoal[i] = iGoal
return lGoal
#i = int(raw_input())
i = 30
timeStart = time.time()
getList(i)
print "Cost: %s" % (time.time() - timeStart)
执行时间:
Cost: 0.280420064926
对比之前的21.9739699364 性能提升78倍!不过需要注意,ctypes模块的加载本身很耗资源,使用不当会起到反效果,例如将i=30改为i=10的情况下,python: 0.000591039657593,而Ctypes则需要0.00165605545044,反而落后3倍的时间。
| anyShare分享到: | |
| |

近期评论