c语言版冒泡排序
#include <iostream>
#include <sstream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
void bubble(int *arr,int length){
int j=length-1;
int i,tmp;
while(j>=0){
i=0;
while(i<j){
if(arr[i]>arr[i+1]){
tmp=arr[i+1];
arr[i+1]=arr[i];
arr[i]=tmp;
}
i++;
}
j--;
}
}
int main(int argc,char* argv[]){
srand(time(NULL));
int N;
stringstream ss;
ss<<string(argv[1]);
ss>>N;
//1).上面是将字符串argv[1]转为整数,
//如果将N的值转为字符串可以stringstream ss;ss<<N; string str1;ss>>str1;
//2).整数和字符串的转化也可使用sprintf和sscanf
//或者直接使用sprintf函数
//sscanf(argv[1],"%d",&N); //将字符串argv[1]转为整数保存到N
//sprintf(N,"%s",argv[1]); //将整数N保存为字符串argv[1]
int s[N];
int len=N/RAND_MAX;
for(int i=0;i<len;i++){
for(int j=0;j<RAND_MAX;j++)
s[i*RAND_MAX+j]=i*RAND_MAX+rand();
}
for(int k=0;k<N%RAND_MAX;k++)
s[len*RAND_MAX+k]=len*RAND_MAX+rand();
clock_t t1=clock();
bubble(s,N);
clock_t t2=clock();
cout<<double(t2-t1)/1000<<endl;
for(int i=20;i<30;i++)
cout<<s[i]<<" ";
cout<<endl;
return 0;
}
结果如下:
def bubble(arr,length):
j=length-1
while j>=0:
i=0
while i<j:
if arr[i]>arr[i+1]:
tmp=arr[i+1]
arr[i+1]=arr[i]
arr[i]=tmp
i+=1
j-=1
if __name__ == '__main__':
import sys
import numpy as np
import time
N=sys.argv[1]
N=int(N)
arr=np.random.randint(0,N,N)
t1=time.clock()
bubble(arr,N)
t2=time.clock()
print('time ellaspe:',t2-t1)
for i in range(20,30,1):
print(arr[i],end=',')
结果如下:
使用一个长度为100,1000,10000,100000的数组,
在相同的机器上执行,Python版执行时间分别是是0.003s,0.375s,37.655s,5418.8s左右,而c语言版本(未使用任何优化编译参数)执行时间只有0s,0s,0.35s,25.054s左右。
相比之下python的性能的确差很多(主要是python中list的操作跟c的数组相比,效率差非常多),但python中很多扩展都是c语言写的,目的就是为了提升效率,python用于数据分析的numpy库就拥有不错的性能。下个实验就验证,如果python使用c语言版本的冒泡排序扩展库,性能会提升多少。
解决方法,可以用python调用c(c++).
1 python调用C/C++可执行程序
paixu.cpp的代码如下:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
void bubble(int *arr,int length){
int j=length-1;
int i,tmp;
while(j>=0){
i=0;
while(i<j){
if(arr[i]>arr[i+1]){
tmp=arr[i+1];
arr[i+1]=arr[i];
arr[i]=tmp;
}
i++;
}
j--;
}
}
int main(){
srand(time(NULL));
const int N=100000;
int s[N];
int len=N/RAND_MAX;
for(int i=0;i<len;i++){
for(int j=0;j<RAND_MAX;j++)
s[i*RAND_MAX+j]=i*RAND_MAX+rand();
}
for(int k=0;k<N%RAND_MAX;k++)
s[len*RAND_MAX+k]=len*RAND_MAX+rand();
clock_t t1=clock();
bubble(s,N);
clock_t t2=clock();
cout<<double(t2-t1)/1000<<endl;
for(int i=20;i<30;i++)
cout<<s[i]<<" ";
cout<<endl;
return 0;
}
python调用c++程序的代码文件tst4.py的内容如下:
import subprocess
import os
cppexe='d:/mytools/paixu.exe'
if os.path.exists(cppexe):
rc,out=subprocess.getstatusoutput(cppexe)
print('rc=%d,\nout=%s'%(rc,out))
#f=subprocess.Popen(cppexe,shell=True,stdout=subprocess.PIPE).stdout.read()
#data=f.decode()
#print(data)
结果如下:
从结果可以看出,对100000个随机数排序,直接执行c++可执行文件paixu.exe,耗时25.054,通过python调用paixu.exe,耗时27.305s左右.
2 python调用C++(类)动态链接库
2.1 首先生成c++动态链接库文件
1). 如果你的python是64位的,由于codeblocks自带的默认的mingw编译器是32位的,所以首先下载mingw64位编译器.地址是https://sourceforge.net/projects/mingw-w64/.
配置如下:
2). 生成动态链接库(dynamic linker library,dll)文件
如果需要使用gdb调试代码的话,还需要配置gdb如下:
3). 编译paixu.cpp文件
这样在项目目录下就会生成可执行文件paixu.exe.
4). 编写pypaixu.py,这里通过在命令行传入参数来确定生成随机数以及要排序的整数个数.
import ctypes
import numpy as np
import time
import sys
l1=ctypes.cdll.LoadLibrary
lib=l1('d:/paixu/bin/debug/paixu.dll')
N=sys.argv[1]
N=int(N)
intN=ctypes.c_int*N
tmp=np.random.randint(0,N,N)
arr=intN(*list(tmp))
t1=time.clock()
lib.bubble(arr,N)
t2=time.clock()
print('time ellaspe:',t2-t1)
for i in range(20,30,1):
print(arr[i],end=',')
传入不同的参数,执行python代码如下: