4. • динамический язык;
• байт код без компиляции;
• GC на счетчике ссылок;
• Global Interpretor Lock;
• если что-то работает медленнее
python’а, это не значит что
python быстрый.
5. • динамический язык;
• байт код без компиляции;
• GC на счетчике ссылок;
• Global Interpretor Lock;
• если что-то работает медленнее
python’а, это не значит что
python быстрый.
6. Еще про ref-counting
• процессы плохая замена
тредам;
• не работает Copy–on–Write;
• мы не можем легко
распараллелить программу,
когда у нас много данных.
7. ...
d = d i c t ( ( i , ’ t h e s t r i n g w i t h %d ’ % i )
for i in x r a n g e ( 5 0 0 ∗ 1 0 0 0 ) )
time . s l e e p (10)
s y s . s t d e r r . w r i t e ( ’ about t o f o r k . . . n ’ )
os . f o r k ( )
f or i , k in d . i t e r i t e m s ( ) :
pass
time . s l e e p (10)
14. Pure C
long sum_th(const struct with_th_t *all,
size_t size) {
long result = 0;
size_t i;
for (i = 0; i < size; ++i) {
result += all[i].th;
}
return result;
}
15. Модуль на C
while ((item = PyIter_Next(iterator)) != NULL) {
PyObject *field = PyObject_GetAttr(
item, interned_th);
if (field == NULL) {
Py_DECREF(result);
Py_DECREF(item);
return NULL;
}
PyObject *nw = PyNumber_Add( result, field);
Py_DECREF(result);
...
23. • читайте FAQ;
• используйте cdef;
• не *q = 0, а q[0] = 0;
• не путайте float и double;
• cdef для переменных, которые
участвуют в циклах;
• cython -a.
24. shlex.split
• Ускорим простую программу
в XX раз.
• За 15 минут.
• Сейчас это займет куда меньше
времени.
25. Задача
127.0.0.1 "it’s query" "client id" 12.0 ...
• str.split не сработает: некоторые
поля окружены кавычками.
• 25 миллионов строк в день.
• 680 миллионов строк в месяц.
26. Что имеем
sm = 0.0
cnt = 0
for line in sys.stdin:
split = shlex.split(line)
try:
sm += float(split[12])
cnt += 1
except ValueError:
pass
27. Что имеем
Используем стандартный shlex.split и файл в 900
строк.
SUMMARY
real time: 0.870 [ 0.875 +-0.004] 0.878
sys time: 0.004 [ 0.007 +-0.002] 0.008
user time: 0.844 [ 0.860 +-0.014] 0.868
≈ 1 мс на строку.
≈ 7 часов на дневной лог
28. Что имеем
Своя, очень простая реализация. Тот же файл.
SUMMARY
real time: 0.603 [ 0.614 +-0.009] 0.621
sys time: 0.000 [ 0.001 +-0.002] 0.004
user time: 0.596 [ 0.601 +-0.006] 0.608
≈ 0.7 мс на строку.
≈ 5 часов на дневной лог
29. Что имеем
Та же реализация, но откомпилированная в
cython. Тот же файл.
SUMMARY
real time: 0.650 [ 0.664 +-0.013] 0.675
sys time: 0.000 [ 0.000 +-0.000] 0.000
user time: 0.640 [ 0.655 +-0.014] 0.668
38. Кроме этого
• на каждый вызов функции надо
преобразовывать данные;
• в вырожденных случаях, это
будет дольше самой функции;
• мы вынуждены переписывать
все места, где мы вызываем
нашу функцию.
39. Решение
• частичная оптимизация;
• cpdef;
• перетаскивание функционала в
cython, а потом в C;
• это не панацея.
41. Копирование vs proxy
proxy:
• каждый раз преобразовывать;
• но есть кеш объектов;
• код на C работает быстро;
• это тот код, который нас
интересует.
45. GIL
• он нужен, пока мы работаем с
python данными;
• в критичных местах, мы не
работаем с python данными;
• мы можем его отпустить.
46. proxy: запрет создания из
python
cdef class _Q:
def __cinit__(self, ....):
....
def __init__(self, ....):
raise TypeError, ""
cpdef _Q Q(....):
cdef _Q q = _Q.__new__(_Q)
return q
47. Кеширование объектов
• попробуйте id;
• попробуйте перенумеровать в
зависимости от частоты;
• убедитесь, что у вас
неизменяемые типы;
• треды...
48. Кеширование прокси
объектов
Python container a[0] a[1] ... a[n]
C struct ... void *extra
container struct Python proxy
49. Кеширование прокси
объектов
Python container a[0] a[1] ... a[n]
C struct ... void *extra
__getitem__
Python proxy container struct next Python proxy ...
50. Кеширование прокси
объектов
cdef _Point point_wrap(point_t *x):
cdef _Point result
if x.extra != NULL:
return <_Point>x.extra
result = _Point.__new__(_Point)
result.inner = x
if is_common_point(x):
print ’cache’
x.extra = <void *>result
return result
51. Мои выводы
• python это удобно;
• С это быстро;
• cython объединяет;
• все будет хорошо.
52. Благодарю за
внимание
shigin@rambler-co.ru
friendfeed.com/shigin