前段時(shí)間寫(xiě)了兩篇文章介紹如何提高Python的運(yùn)行效率,一篇是從python語(yǔ)言本身的角度去介紹的,另一篇是從解釋器角度(利用PyPy),有興趣的可以找著看看。從另外一個(gè)角度來(lái)介紹如何提高python運(yùn)行效率,那就是利用c/c++來(lái)擴(kuò)展python提高性能。我們知道python官方網(wǎng)站上下載的python解釋器源碼是用c語(yǔ)言編寫(xiě)的,所以,也可以利用c/c++來(lái)擴(kuò)展它,以獲得較優(yōu)的執(zhí)行性能。Python提供了API接口,是我們很方便的能進(jìn)行擴(kuò)展,所有這些API都包含在Python.h的頭文件里,在編寫(xiě)c代碼時(shí)引入該頭文件即可。下面來(lái)講講我初用c/c++擴(kuò)展python的經(jīng)歷吧。申明所有系統(tǒng)Ubuntu 16.04 LTS。
成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿(mǎn)足客戶(hù)于互聯(lián)網(wǎng)時(shí)代的天峻網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!(一)Ubuntu下如何編譯.c文件
說(shuō)實(shí)話,進(jìn)行這部分學(xué)習(xí)時(shí),第一困擾我的問(wèn)題就是不知道怎么在Ubuntu下編譯.c文件,以前在大學(xué)的時(shí)候,用的是Windows系統(tǒng),安裝了visual studio 2010,代碼編寫(xiě),編譯都很方便。沒(méi)有在Ubuntu下用c語(yǔ)言開(kāi)發(fā),所以這部分知道還不太了解,好在網(wǎng)上資料非常豐富,很快就能找到相應(yīng)的資料。其實(shí)Ubuntu系統(tǒng)自帶c語(yǔ)言編譯器,那就是gcc。不信你可以打開(kāi)終端,輸入命名:gcc --version,顯示如下信息:
如果沒(méi)有的話,你也可自己安裝,安裝命令如下:
sudo apt-get install gcc
建議還要安裝一個(gè)build-essentiall包,作用是提供編譯程序必須軟件包的列表信息,也就是說(shuō) 編譯程序有了這個(gè)軟件包它才知道 頭文件在哪 ,才知道庫(kù)函數(shù)在哪,還會(huì)下載依賴(lài)的軟件包 , 最后才組成一個(gè)開(kāi)發(fā)環(huán)境。
好了,現(xiàn)在寫(xiě)個(gè)簡(jiǎn)單的.c文件吧。
打開(kāi)終端,輸入命令vim hello.c,當(dāng)然,你也可以用gedit來(lái)編輯代碼,只要文件擴(kuò)展名不搞錯(cuò)了就行。代碼如下:
#include<stdio.h> int main() { int i; for(i=0;i<3;i++) printf("hello,gcc!\n"); }
然后保存文件并退出。編譯成可執(zhí)行文件,命令如下:
gcc hello.c -o hello
然后輸入./hello執(zhí)行該文件。效果如下圖。
這里只是簡(jiǎn)單的講了一下linux的gcc的使用方法,關(guān)于它更多的用法可以在網(wǎng)上查資料,在此不做過(guò)多介紹。
(二)使用C/C++擴(kuò)展Python
1.先利用Python提供的接口,編寫(xiě)一個(gè)漢語(yǔ)一定功能.c文件,比如判斷一個(gè)數(shù)是不是素?cái)?shù)。在這里文件名為test.c,使用c語(yǔ)言實(shí)現(xiàn)后再使用Python進(jìn)行包裝。代碼如下:
#include<Python.h> static PyObject *pr_isprime(PyObject *self,PyObject *args){ int n,num; if(!PyArg_ParseTuple(args,"i",&num)) return NULL; if(num<1){ return Py_BuildValue("i",0); } n=num-1; while(n>1){ if(num%n==0) return Py_BuildValue("i",0); n--; } return Py_BuildValue("i",1); } static PyMethodDef PrMethods[]={ {"isPrime",pr_isprime,METH_VARARGS,"check if an input numbe is prime or not."}, {NULL,NULL,0,NULL} }; void initpr(void){ (void) Py_InitModule("pr",PrMethods); }
PyObject是Python對(duì)象機(jī)制的基礎(chǔ),所有得對(duì)象都擁有一些相同的內(nèi)容,而這些內(nèi)容在PyObject中定義。
上面的代碼包括三部分:
一是導(dǎo)出函數(shù),C模塊對(duì)外暴露的接口函數(shù)pr_isprime,帶有self和args兩個(gè)參數(shù),其中參數(shù)args中包含了python解釋器要傳遞給c函數(shù)的所有參數(shù),通常使用PyArg_ParseTuple()來(lái)獲得這些參數(shù)。
二是初始化函數(shù),以便python解釋器能夠?qū)δK進(jìn)行初始化,初始化時(shí)要以init開(kāi)頭,如initx。
第三是方法列表,提供給外部的python程序使用的一個(gè)C模塊函數(shù)名稱(chēng)映射表PrMethods。它是一個(gè)PyMethodDef結(jié)構(gòu)體,其中成員依次表示方法名、導(dǎo)出函數(shù)、參數(shù)傳遞方式和方法描述。
參數(shù)傳遞方式一般設(shè)置為METH_VARARGS,如果想傳遞關(guān)鍵字參數(shù),你可以讓它與MRTH_KEYWORDS進(jìn)行或運(yùn)算;如果不想接受任何參數(shù),可以用METH_NOARGS,該結(jié)構(gòu)體必須以{NULL,NULL,0,NULL}所表示的一條空記錄結(jié)尾。
至于為什么這樣做,可能與Python.h里面的函數(shù)有關(guān),該部分我還未仔細(xì)研究,所以這篇文章也叫題目用了“初用”,如果有以后弄清楚了,我會(huì)“再用”,與大家分享學(xué)習(xí)經(jīng)驗(yàn)。
2.編寫(xiě)setup.py腳本
代碼如下:
rom distutils.core import setup,Extension module = Extension('pr',sources=['test.c']) setup(name='Pr test',version = '1.0',ext_modules=[module])
distutils包是可以用來(lái)在Python環(huán)境中構(gòu)建和安裝額外的模塊。新的模塊可以是純Python的,也可以是用C/C++寫(xiě)的擴(kuò)展模塊,或者可以是Python包,包中包含了由C和Python編寫(xiě)的模塊。在此不做過(guò)多介紹,有興趣可以在網(wǎng)上找資料了解下。
3.使用python setup.py build進(jìn)行編譯,系統(tǒng)會(huì)自動(dòng)在當(dāng)前目錄生成一個(gè)build子目錄,里面包含一個(gè).so文件、.o文件。看看我的操作結(jié)果吧
執(zhí)行python setup.py build命令后,系統(tǒng)確實(shí)在當(dāng)前目錄生成了一個(gè)build子目錄,并且有一個(gè).so文件、.o文件。
4.將生成的.so文件復(fù)制到/usr/local/lib/python2.7/dist-packages下,或者將.so文件所在目錄路徑添加到sys.path中,然后就可以使用該C擴(kuò)展模塊了。如下圖:
(三)簡(jiǎn)單測(cè)試下性能
代碼如下:
#coding=utf-8 import pr import datetime def is_prime(n): if n <= 1:# return False else: a = n - 1 while(a > 1): if n % a == 0: return True a = a - 1 return False t1 = datetime.datetime.now() is_prime(8888888) t2 = datetime.datetime.now() pr.isPrime(8888888) t3 = datetime.datetime.now() print t3 - t2,t2 - t1
其中is_prime()是用python寫(xiě)的判斷一個(gè)正數(shù)是不是素?cái)?shù)。它的循環(huán)算法與pr模塊里面的isPrime()是一樣的,但是效率卻有很大差異,看看下圖運(yùn)行結(jié)果。
很顯然用c擴(kuò)展的那個(gè)包里的函數(shù)計(jì)算速度快而且是塊近20倍,數(shù)值越大,速度上的差距越大,有興趣的話,可以動(dòng)手試下。當(dāng)然這只是一個(gè)定性分析。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。
標(biāo)題名稱(chēng):初用C/C++擴(kuò)展Python,提高性能-創(chuàng)新互聯(lián)
分享地址:http://www.rwnh.cn/article0/csghio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、動(dòng)態(tài)網(wǎng)站、ChatGPT、面包屑導(dǎo)航、網(wǎng)站策劃、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容
營(yíng)銷(xiāo)型網(wǎng)站建設(shè)知識(shí)