當前位置:
首頁 > 知識 > Python 調用 C 模塊以及性能分析

Python 調用 C 模塊以及性能分析

(點擊

上方藍字

,快速關注我們)




來源:Xjng



www.cnblogs.com/Xjng/p/5120853.html


如有好文章投稿,請點擊 → 這裡了解詳情




一.c,ctypes和python的數據類型的對應關係





  • ctypes type ctype Python type



  • c_char char 1-character string



  • c_wchar wchar_t 1-character unicode string



  • c_byte char int/long



  • c_ubyte unsigned char int/long



  • c_short short int/long



  • c_ushort unsigned short int/long



  • c_int int int/long



  • c_uint unsigned int int/long



  • c_long long int/long



  • c_ulong unsigned long int/long



  • c_longlong __int64 or long long int/long



  • c_ulonglong unsigned __int64 or unsigned long long int/long



  • c_float float float



  • c_double double float



  • c_char_p char * (NUL terminated) string or None



  • c_wchar_p wchar_t * (NUL terminated) unicode or None



  • c_void_p void * int/long or None



2.操作int





>>>

from ctypes import *


>>>

c

=

c_int

(

34

)


>>>

c

c_int

(

34

)


>>>

c

.

value


34


>>>

c

.

value

=

343


>>>

c

.

value


343




3.操作字元串





>>>

p

=

create_string_buffer

(

10

)


>>>

p

.

raw


"x00x00x00x00x00x00x00x00x00x00"


>>>

p

.

value

=

"fefefe"


>>>

p

.

raw


"fefefex00x00x00x00"


>>>

p

.

value

=

"fefeeeeeeeeeeeeeeeeeeeeeee"

#字元串太長,報錯


Traceback

(

most recent call

last

)

:


File

""

,

line

1

,

in

<

module

>


ValueError

:

string

too long




4.操作指針





>>>

i

=

c_int

(

999

)


>>>

pi

=

pointer

(

i

)


>>>

pi


<

__main__

.

LP_c_int object

at

0x7f7be1983b00

>


>>>

pi

.

value


Traceback

(

most recent call

last

)

:


File

""

,

line

1

,

in

<

module

>


AttributeError

:

"LP_c_int"

object

has no

attribute

"value"


>>>

pi

.

contents


c_int

(

999

)


>>>

pi

.

contents

=

c_long

(

34343

)


>>>

pi

.

contents


c_int

(

34343

)






  • 通過pointer獲取一個值的指針



  • 通過contents獲取一個指針的值




5.c的結構體





#定義一個c的structure,包含兩個成員變數x和y


>>>

class

POINT

(

Structure

)

:


...

_fields_

=

[(

"x"

,

c_int

),(

"y"

,

c_int

)]


...


>>>

point

=

POINT

(

2

,

4

)


>>>

point


<

__main__

.

POINT object

at

0x7f7be1983b90

>


>>>

point

.

x

,

point

.

y


(

2

,

4

)


>>>

porint

=

POINT

(

y

=

2

)


>>>

porint


<

__main__

.

POINT object

at

0x7f7be1983cb0

>


>>>

point

=

POINT

(

y

=

2

)


>>>

point

.

x

,

point

.

y


(

0

,

2

)


定義一個類型為

POINT

的數組


>>>

POINT_ARRAY

=

POINT

*

3


>>>

pa

=

POINT_ARRAY

(

POINT

(

2

,

3

),

POINT

(

2

,

4

),

POINT

(

2

,

5

))


>>>

for

i

in

pa

:

print

pa

.

y


...


Traceback

(

most recent call

last

)

:


File

""

,

line

1

,

in

<

module

>


AttributeError

:

"POINT_Array_3"

object

has no

attribute

"y"


>>>

for

i

in

pa

:

print

i

.

y


...


3


4


5




6.訪問so文件




1.創建一個c文件





#include


int

hello_world

(){


printf

(

"Hello World
"

);


return

0

;


}


int

main

(){


hello_world

();


return

0

;


}




2.編譯成動態鏈接庫





gcc hello_world.c -fPIC -shared -o hello_world.so




3.python中調用庫中的函數





from ctypes import cdll


c_lib

=

cdll

.

LoadLibrary

(

"./hello_world.so"

)


c_lib

.

hello_world

()




二.測試c的性能和python的差別




sum.c





int

sum

(

int

num

){


long

sum

=

0

;


int

i

=

0

;


for

(

i

=

1

;

i

<=

num

;

i

++

){


sum

=

sum

+

i

;


};


return

sum

;


}


int

main

(){


printf

(

"%d"

,

sum

(

10

));


return

0

;


}






  • 測試方案:計算1-100的和



  • 測試次數:100萬次




1. 直接用c來執行,通linux 的time命令來記錄執行的用時




sum.c:





#include


int

sum

(

int

num

){


long

sum

=

0

;


int

i

=

0

;


for

(

i

=

1

;

i

<=

num

;

i

++

){


sum

=

sum

+

i

;


};


return

sum

;


}


int

main

(){


int

i

;


for

(

i

=

0

;

i

<

1000000

;

i

++

){


sum

(

100

);


}


return

0

;


}




測試結果的例子:






  • real 1.16



  • user 1.13



  • sys 0.01




2.通過Python調用so文件和python的測試結果




sum_test.py:





def sum_python

(

num

)

:


s

=

0


for

i

in

xrange

(

1

,

num

+

1

)

:


s

+=

i


return

s




from ctypes import cdll



c_lib

=

cdll

.

LoadLibrary

(

"./sum.so"

)




def sum_c

(

num

)

:


return

c_lib

.

sum

(

num

)




def test

(

num

)

:


import timeit



t1

=

timeit

.

Timer

(

"c_lib.sum(%d)"

%

num

,

"from __main__ import c_lib"

)


t2

=

timeit

.

Timer

(

"sum_python(%d)"

%

num

,

"from __main__ import sum_python"

)


print

"c"

,

t1

.

timeit

(

number

=

1000000

)


print

"python"

,

t2

.

timeit

(

number

=

1000000

)




if

__name__

==

"__main__"

:


test

(

100

)




測試結果的例子





c

1.02756714821


python

7.90672802925




3.測試erlang的測試結果




剛剛學了erlang,那就一起測試一下erlang的運算性能




sum.erl:





-

module

(

sum

).


-

export

([

sum

/

2

,

sum_test

/

2

]).


sum

(

0

,

Sum

)

->


Sum

;


sum

(

Num

,

Sum

)

->


sum

(

Num

-

1

,

Sum

+

Num

).


sum_test

(

Num

,

0

)

->


0

;


sum_test

(

Num

,

Times

)

->


sum

(

Num

,

0

),


sum_test

(

Num

,

Times

-

1

).




調用:





timer:tc(sum,sum_test,[100,1000000]).




測試結果的例子:





{2418486,0}




4.測試結果




用上面的測試方法,進行10次測試,去除最大值和最小值,再計算平均值,得出:







單位:秒






  • 求和的運行,使用的內存比較小,但是佔用CPU資源比較多。



  • 原生的C是最快的,Python調用c會稍微慢一點,原因是計算100的和的操作是在c裡面做的,而執行100萬次的邏輯是在python做的



  • erlang的性能雖然比c稍慢,但是也是不錯的,



  • Python的運行效率慘不忍睹。。。




看完本文有收穫?請轉

發分享給更多人


關注「P

ython開發者」,提升Python技能


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

如何用Python從海量文本抽取主題?
使用Python自动提取内容摘要
Python Virtualenv 介紹
手把手教你如何用 Python 做情感分析

TAG:Python |

您可能感興趣

Python os模塊的使用
Python3 Python 常用內建模塊
Pycharm 導入 Python 包、模塊
Molex 汽車功率輸出模塊充分利用Microchip Technology 的創新性設備
Python OS模塊簡介
用於多元時間序列的 Python 模塊——Seglearn
使用 Python 和 Pygame 模塊構建一個遊戲框架
針對間諜軟體InvisiMole的RC2CL模塊分析
Python的hashlib模塊和hmac模塊
一文概述用 python 的 scikit-image 模塊進行圖像分割
Python-GUI Tkinter模塊
SpringMVC + security模塊 框架整合詳解
利用ngx_python模塊嵌入到Python腳本
python基礎之變數類型number(math模塊)
Astro C40 TR是一款擁有PlayStation授權的模塊化手柄
Additive Works推出用於生成3D列印支撐的新Amphyon模塊
Python模塊和包初探
NI FlexRIO 使用Kintex UltraScale FPGA和夾層I/O模塊,滿足客戶定製前端開發
實戰python中Random模塊使用
安卓 P-ify Xposed模塊讓安卓Oreo使用Android P功能