http://blog.csdn.net/king_on/article/details/8092399
http://blog.csdn.net/lcz_ptr/article/details/7824414
百度搜 python swig ubuntu
整理
1. 编写c文件
Bit.h
#ifndef BIT_H
#define BIT_H
//create: 2012-10-19
//version: 1.0
#define CHAR_LENGTH sizeof(unsigned char)
//Bit模拟位操作
typedef struct
{
unsigned char *pArray;//指向一个字符型数组,用以存储bit位
unsigned long length;//记录pArray的长度, 字符个数
unsigned long used;//记录用户使用的bit位
}Bit;
//创建Bit对象
//@len: 初始化bit位数
//@return: 返回一个指向Bit对象的指针, 该指针需要使用freeBit销毁
Bit* createBit(unsigned long len);
//设置bit位
//@pb:指向Bit的一个对象, 如果为NULL, 返回1
//@index: 需要设置的bit位, 范围应当是 (0~used)
//@value: bit位的值, (0,1)
//@return: 成功返回0, 如果出现pb==NULL, index out of range, value!=0 and value!=1, 返回1
int setBit(Bit *pb,unsigned long index, int value);
//获取bit位
//@pb:指向Bit的一个对象, 如果为NULL, 返回1
//@index: 需要设置的bit位, 范围应当是 (0~used)
//@return: 成功返回0, 如果出现pb==NULL, index out of range, 返回1
int getBit(Bit *pb,unsigned long index);
//返回使用的长度
//@pb: 如果pb==NULL, return -1
int bitLength(Bit *pb);
//销毁Bit对象
void freeBit(Bit *pb);
#endif
Bit.c
#include "Bit.h"
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//创建Bit对象
//@len: 初始化bit位数, len>=0
//@return: 返回一个指向Bit对象的指针, 该指针需要使用freeBit销毁
Bit* createBit(unsigned long len)
{
if(len<0)
return NULL;
Bit *pb=(Bit*)malloc(sizeof(Bit));
if(len>0)
{
pb->length=(len-1)/CHAR_LENGTH+1;
pb->pArray=(char*)malloc(sizeof(char)*pb->length);
pb->used=len;
}else
{
pb->length=0;
pb->pArray=NULL;
pb->used=len;
}
return pb;
}
//设置bit位
//@pb:指向Bit的一个对象, 如果为NULL, 返回1
//@index: 需要设置的bit位, 范围应当是 [0~used)
//@value: bit位的值, (0,1)
//@return: 成功返回0, 如果出现pb==NULL, index out of range, value!=0 and value!=1, 返回1
int setBit(Bit *pb,unsigned long index, int value)
{
if(pb==NULL || pb->pArray==NULL || index<0 || index>=pb->used || (value!=0 && value!=1))
return 1;
unsigned long a=index/CHAR_LENGTH;
unsigned long b=index%CHAR_LENGTH;
if(value==0)
{
pb->pArray[a]&=(UCHAR_MAX^(1<<b));
//printf("%d\n",pb->pArray[a]);
}else
{
pb->pArray[a]|=(1<<b);
//printf("%d\n",pb->pArray[a]);
}
return 0;
}
//获取bit位
//@pb:指向Bit的一个对象, 如果为NULL, 返回1
//@index: 需要设置的bit位, 范围应当是 [0~used)
//@return: 成功返回0, 如果出现pb==NULL, index out of range, 返回1
int getBit(Bit *pb,unsigned long index)
{
if(pb==NULL || pb->pArray==NULL || index<0 || index>=pb->used)
return 1;
unsigned long a=index/CHAR_LENGTH;
unsigned long b=index%CHAR_LENGTH;
//printf("%d\n",pb->pArray[a]&(1<<b));
if((pb->pArray[a]&(1<<b))==0)
return 0;
else
return 1;
}
//返回使用的长度
//@pb: 如果pb==NULL, return -1
int bitLength(Bit *pb)
{
if(pb==NULL || pb->pArray==NULL)
return -1;
return pb->used;
}
//销毁Bit对象
void freeBit(Bit *pb)
{
if(pb==NULL)
return;
if(pb->pArray!=NULL)
{
free(pb->pArray);
pb->pArray=NULL;
}
free(pb);
}
2. 编写SWIG使用的swg文件
Bit.i
%module Bit #module name
%{
#include "Bit.h" #加入Bit_wrap.c文件
%}
#需要导出到python的函数
extern Bit* createBit(unsigned long len);
extern int setBit(Bit *pb,unsigned long index, int value);
extern int getBit(Bit *pb,unsigned long index);
extern int bitLength(Bit *pb);
extern void freeBit(Bit *pb);
3. 编译
3.1 使用Bit.i生成wrap文件,该命令得到Bit_wrap.c Bit.py
[username]$ swig -python Bit.i
3.2 编译Bit.c Bit_wrap.c文件,其中PYTHON_INCLUDE为python安装目录下的include文件夹, 如/usr/program/python/include/python.2.7username]$ gcc -c
[username]$ gcc -c -fpic Bit.c Bit_wrap.c -I${PYTHON_INCLUDE}
3.3 连接得到动态库
[username]$ gcc -shared Bit.o Bit_wrap.o -o _Bit.so
注意输出库文件为_Bit.so, 有下划线和模块名称组成
4.使用,这里以计算一亿一下的素数个数来演示
将Bit.py和_Bit.so文件复制到需要的位置
编写prime_count.py
#coding=utf-8
#create-2012-10-17
#version: 1.0
#计算小于1亿的素数个数
import time
from Bit import *
MAX=100000000
count=1
#0 表示素数
#1 表示已经去除
start_time=time.time()
len=MAX/2-1
b=createBit(len)
def remove(idx):
i=idx
global b
while i<len:
#b[i]=1
setBit(b,i,1)
i+=2*idx+3
for i in range(3,MAX,2):
if getBit(b,(i-3)/2)==0:
#素数
count+=1
remove((i-3)/2)
end_time=time.time()
print count
print end_time-start_time
使用方法和其他python提供的模块一样
5.附计算结果
使用以上方法(c扩展python)得到结果为:
5761455(素数个数)
113.465720892(second)
另外,如果直接使用python模拟bit,并同样计算一亿一下的素数个数,结果为
5761455(素数个数)
293.473055124(second)
可以看到,性能提升非常明显(接近3倍),当然这只是一个例子,并不具有太多代表性
另附,同样的方法,如果是c语言,调用我们实现的Bit的话结果为:
5761455(素数个数)
5(second)