用 shedskin 将你的 python 程序转成 C++ 代码
最近在用 python 写一些东西(puzzleup.com上的题啥的),python 写起来很快也很方便,但是当遇到大量数学运算的时候可能就会很慢,于是我就 google 了一下 python 加速的方法,常用的 pysco 就不用说了,这是最简单的方法,但是效果可能不是最好的,传说 pypy 能够将 python 翻译成 c/java 能代码,但是使用的过程中老是遇到错误(什么:[translation:ERROR] KeyError: ‘target’ bulabula),而且编译这个东西耗费了我 >24 h,喜特!猛回头,瞅见了 shedskin,传说这个东东能将 python 翻译成C++,抱着试试看的心情,我就安装上了,结果一试,还真的有快感诶,赫赫!
使用方法:
普通的话就直接:shedskin xxx.py 就可以了,注意 xxx.py 里面只能有数字,字母和下划线,其他滴不要(路径都不能有,刚刚没太注意,结果老是出警告:*ERROR*:./xxx.py: module names should consist of letters, digits and underscores),会在当前目录下生成一个 xxx.cpp, xxx.hpp 和一个 Makefile,完事以后直接 make 就会编译出一个可执行程序来的。为了验证这个玩意是否好使,我找了一个以前和骨头,lerosua 等童鞋一起做欧拉工程的一道运算量较大的题来做实验。
题目是:
http://projecteuler.net/index.php?section=problems&id=10
小于10的所有质数的和是 2 + 3 + 5 + 7 = 17。求小于2000000的所有质数的和。
我写了一个 python 版本(鉴于本人的 python 极菜加之有数学恐惧症,大家对该程序的运行效率不要抱太大希望,只限于能够算出答案而已):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/usr/bin/env python # -*- coding: utf-8 -*- # Name: 007-xiooli.py # Author: xiooli # Email: <xioooli[at]yahoo.com.cn> # Site: http://joolix.com # Licence: GPLv3 # Version: 091024 def is_prime(prm,i): j=0 while prm[j]*prm[j] <= i: if i%prime[j] == 0: return False j+=1 return True prime=[2] for k in xrange(3,2000000,2): if is_prime(prime,k): prime.append(k) print sum(prime) |
然后是 lerosua 童鞋的 C 版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* * ===================================================================================== * * Filename: 003-lerosua.c * * Description: * * Version: 1.0 * Created: 2009年10月21日 11时37分49秒 * Revision: none * Compiler: gcc * * Author: lerosua (), lerosua@gmail.com * Company: cyclone * * ===================================================================================== */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define MAX 1024000 /** 简单的素数集合*/ static long long primum[MAX] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; static long int count = 10; /** 填加10001个素数进素数数组*/ void fill_prime(long long num) { long long i = 31; long int j = 0; for (; i < num; i = i + 2) { int flag = 1; long long m=(long long)sqrt(i)+1; for (j = 0; primum[j] < m; j++) { if (i % primum[j] == 0) { flag = 0; break; } } if (flag) { primum[count++] = i; if(i>num) return; } if(count>MAX){ printf("error%d\n",count); exit(1); } } } int main(int argc, char *argv[]) { int i; long long sum=0L; fill_prime(2000000); for(i=0;i<count;i++) if(primum[i]<2000000) sum+=primum[i]; printf("count %d \n",count); printf("%lld\n",sum); //printf("%ld\n",primum[5]); return 0; } |
下面正面 PK :
1 2 3 4 5 6 7 | xiooli@XIOOLI> time ./010-lerosua count 148933 142913828922 ./010-lerosua 0.83s user 0.00s system 95% cpu 0.875 total xiooli@XIOOLI> time python 010-xiooli.py 142913828922 python 010_xiooli.py 19.91s user 0.01s system 93% cpu 21.191 total |
咳咳,差距呀~~~(厚颜无耻的说一句,比代码行数的话,我可不差哦。。)
好了,闲话少说,今天咱是有备而来,xiooli 要祭出杀手锏了:
1 2 3 4 5 6 7 8 9 10 11 12 13 | xiooli@XIOOLI> shedskin 010_xiooli.py *** SHED SKIN Python-to-C++ Compiler 0.2 *** Copyright 2005-2009 Mark Dufour; License GNU GPL version 3 (See LICENSE) [iterative type analysis..] ** iterations: 2 templates: 78 [generating c++ code..] xiooli@XIOOLI> make g++ -O2 -pipe -Wno-deprecated -I. -I/usr/lib/shedskin-0.2/lib /usr/lib/shedskin-0.2/lib/builtin.cpp 010_xiooli.cpp /usr/lib/shedskin-0.2/lib/re.cpp -lgc -lpcre -o 010_xiooli xiooli@XIOOLI> time ./010_xiooli 142913828922 ./010_xiooli 0.53s user 0.00s system 94% cpu 0.561 total |
呵呵,生成的那个 cpp 和 hpp 乱七八糟的,加之我又不懂 C++,就不列出来了。
居然比 lerosua 童鞋辛辛苦苦写的那一大堆 C 的还要快 0.2 s 多呢,呵呵,shedskin 真是做题作弊之良器也阿。
ps:相信大点的程序要用 shedskin 转 C++ 的话挺够呛的,不过,可以把 python 程序里面的运行瓶颈部分拿出来转成 C++, 于整个程序的运行效率提高应该有很大的帮助呢。另外 shedskin 不是很灵光,python 里面一些很灵活的东西要写得比较死它才容易认,反正有提示的,遇到出错再改 py 文件。
窃笑中:估计 lerosua 童鞋要郁闷了。

最近评论