У меня есть этот код Pythonпитон к проблеме производительности C
def transferIntListToIntArray(sourceTuple):
myArrayLen = len(sourceTuple)
if myArrayLen > 0:
targetArray = (c_int * myArrayLen) (*sourceTuple)
return targetArray
else:
return
def transformIntTupleToIntTab(Input):
if Input != None:
if type(Input) == int:
Input = (Input,)
return transferIntListToIntArray(Input);
else:
return None;
def myfunc(input):
inputTab = transformIntTupleToIntTab(input)
mylib.myfuncC.argtype = [type(inputTab)]
return mylib.myfuncC(inputTab)
У меня есть питон файл с тысячами вызовов функции питона MyFunc, как, что, например (MyFunc ((0,1,2,3)) и если я пытаюсь оценить сроки питона кода это питон строка коды имеет важную стоимость:.
targetArray = (c_int * myArrayLen) (*sourceTuple)
0,1 - 0,2 сек для 10000 вызовов этой функции (Python 2.5.1) Здесь только основные пример, но мой реальный код имеет несколько преобразований кортежа python в int * или double * в C, и мне бы хотелось чтобы знать, как написать более эффективный код Python
пример:
import time
from ctypes import *
from cmath import *
def transferIntListToIntArray(sourceTuple):
myArrayLen=len(sourceTuple)
if myArrayLen>0:
targetArray = (c_int * myArrayLen) (*sourceTuple)
return targetArray
else:
return
def transformIntTupleToIntTab(Input):
if Input != None:
if type(Input) == int:
Input = (Input,)
return transferIntListToIntArray(Input);
else:
return None;
def myfunc(iCurve):
iCurveTab = transformIntTupleToIntTab(iCurve)
return 0
test = (0,1,2,3,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,55,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5)
start = time.clock()
for i in range(100000):
myfunc(test)
print "done, elapsed wall clock time (win32) in seconds: " , time.clock() - start
сделано, истекшее настенные часы (win32) в секундах: +0,497456968189
же пример в Python 2.7 1,65 секунды (странное)
Python докладываю:
done, elapsed wall clock time (win32) in seconds: 0.582374385947
400091 function calls in 0.590 CPU seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.590 0.590 <string>:1(<module>)
1 0.001 0.001 0.590 0.590 {execfile}
1 0.057 0.057 0.589 0.589 tupletest.py:1(<module>)
100000 0.035 0.000 0.526 0.000 tupletest.py:22(myfunc)
100000 0.068 0.000 0.491 0.000 tupletest.py:14(transformIntTupleToIntTab)
100000 0.417 0.000 0.423 0.000 tupletest.py:5(transferIntListToIntArray)
100003 0.006 0.000 0.006 0.000 {len}
1 0.004 0.004 0.005 0.005 __init__.py:4(<module>)
1 0.002 0.002 0.002 0.002 {range}
1 0.000 0.000 0.000 0.000 _endian.py:4(<module>)
4 0.000 0.000 0.000 0.000 __init__.py:83(CFUNCTYPE)
2 0.000 0.000 0.000 0.000 __init__.py:211(POINTER)
1 0.000 0.000 0.000 0.000 __init__.py:291(CDLL)
1 0.000 0.000 0.000 0.000 __init__.py:335(PyDLL)
1 0.000 0.000 0.000 0.000 __init__.py:441(PYFUNCTYPE)
1 0.000 0.000 0.000 0.000 __init__.py:346(WinDLL)
4 0.000 0.000 0.000 0.000 struct.py:43(calcsize)
1 0.000 0.000 0.000 0.000 __init__.py:322(__getattr__)
1 0.000 0.000 0.000 0.000 __init__.py:370(OleDLL)
1 0.000 0.000 0.000 0.000 __init__.py:384(__getattr__)
1 0.000 0.000 0.000 0.000 __init__.py:329(__getitem__)
2 0.000 0.000 0.000 0.000 __init__.py:309(__init__)
1 0.000 0.000 0.000 0.000 {_ctypes.LoadLibrary}
3 0.000 0.000 0.000 0.000 struct.py:35(_compile)
1 0.000 0.000 0.000 0.000 {_ctypes.set_conversion_mode}
4 0.000 0.000 0.000 0.000 __init__.py:381(__init__)
2 0.000 0.000 0.000 0.000 {time.clock}
18 0.000 0.000 0.000 0.000 {_ctypes.sizeof}
3 0.000 0.000 0.000 0.000 __init__.py:101(CFunctionType)
1 0.000 0.000 0.000 0.000 {isinstance}
1 0.000 0.000 0.000 0.000 __init__.py:442(CFunctionType)
1 0.000 0.000 0.000 0.000 __init__.py:144(c_short)
1 0.000 0.000 0.000 0.000 __init__.py:380(LibraryLoader)
2 0.000 0.000 0.000 0.000 {setattr}
1 0.000 0.000 0.000 0.000 _endian.py:22(_swapped_meta)
1 0.000 0.000 0.000 0.000 __init__.py:340(_FuncPtr)
1 0.000 0.000 0.000 0.000 __init__.py:136(py_object)
1 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects}
1 0.000 0.000 0.000 0.000 _endian.py:45(BigEndianStructure)
1 0.000 0.000 0.000 0.000 __init__.py:181(c_ulonglong)
1 0.000 0.000 0.000 0.000 __init__.py:167(c_float)
1 0.000 0.000 0.000 0.000 __init__.py:147(c_ushort)
1 0.000 0.000 0.000 0.000 __init__.py:178(c_longlong)
1 0.000 0.000 0.000 0.000 __init__.py:197(c_char)
1 0.000 0.000 0.000 0.000 __init__.py:305(_FuncPtr)
1 0.000 0.000 0.000 0.000 __init__.py:376(_FuncPtr)
1 0.000 0.000 0.000 0.000 __init__.py:153(c_ulong)
1 0.000 0.000 0.000 0.000 __init__.py:243(c_wchar)
1 0.000 0.000 0.000 0.000 __init__.py:204(c_void_p)
1 0.000 0.000 0.000 0.000 __init__.py:187(c_ubyte)
1 0.000 0.000 0.000 0.000 __init__.py:201(c_char_p)
1 0.000 0.000 0.000 0.000 __init__.py:240(c_wchar_p)
1 0.000 0.000 0.000 0.000 __init__.py:150(c_long)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 __init__.py:193(c_byte)
1 0.000 0.000 0.000 0.000 __init__.py:170(c_double)
1 0.000 0.000 0.000 0.000 __init__.py:357(HRESULT)
1 0.000 0.000 0.000 0.000 __init__.py:350(_FuncPtr)
Пример с 2 вкладки: (цель здесь заключается в преобразовании iCurve1 и iCurve2 в Int * для функции C) по телефону mylibC.myfunC(iCurveTab1 , iCurveTab2)
и код C является myfuncC(int *iCurveTab1, int *iCurveTab2)
import time
from ctypes import *
from cmath import *
def transferIntListToIntArray(sourceTuple):
myArrayLen=len(sourceTuple)
if myArrayLen>0:
targetArray = (c_int * myArrayLen) (*sourceTuple)
return targetArray
else:
return
def transformIntTupleToIntTab(Input):
if Input != None:
if type(Input) == int:
Input = (Input,)
return transferIntListToIntArray(Input);
else:
return None;
def myfunc(iCurve1, iCurve2):
iCurveTab1 = transformIntTupleToIntTab(iCurve1)
iCurveTab2 = transformIntTupleToIntTab(iCurve2)
return 0
test = (0,1,2,3,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,55,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5)
start = time.clock()
for i in range(100000):
myfunc(test, test)
print "done, elapsed wall clock time (win32) in seconds: " , time.clock() - start
В Python 2.5: сделано, часы истекшее стены (win32) в секундах : 0,96631573455
в Python 2.7: сделан, истекшее время настенных часов (win32) в секундах: 3,25996918937
- как я могу улучшить этот питон код? (Хорошая предыдущая идея deets не работает, потому что iCurveTab1 и iCurveTab2 будет использовать тот же указатель C
- кажется, есть регресс в Python 2.7 из-за этого кода
Мой реальный код с с интерфейсом кода Python mytest.py
import time
from ctypes import *
from cmath import *
def transferIntListToIntArray(sourceTuple):
myArrayLen=len(sourceTuple)
if myArrayLen>0:
targetArray = (c_int * myArrayLen) (*sourceTuple)
return targetArray
else:
return
def transformIntTupleToIntTab(Input):
if Input != None:
if type(Input) == int:
Input = (Input,)
return transferIntListToIntArray(Input);
else:
return None;
def myfunc(iCurve1, iCurve2):
iCurveTab1 = transformIntTupleToIntTab(iCurve1)
iCurveTab2 = transformIntTupleToIntTab(iCurve2)
return mylibC.myfuncC(len(iCurveTab1), len(iCurveTab2), iCurveTab1, iCurveTab2)
C Код
void myfuncC(int ilen1, int ilen2, int *piCurve1, int *piCurve2)
{
return;
}
если iCurveTab1 и iCurveTab2 один и тот же кэш piCur ve1 = piCurve2 и это является проблемой, поскольку значения стираются
Мой питон, который исполняется:
from mytest *
myfunc((1,2,3,4),(7,8,9,10,11))
Благодарности
Некоторые nitpicks: Вам не нужно semicola, где вы используете их, проверяя Нискол идиоматически сделано с «является» -оператором (Foo является None) – deets