16
Быстрые конструкции в python

Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Embed Size (px)

DESCRIPTION

В своем докладе Олег расскажет о замене стандартных функций на более быстрые и об ускорении работы python. Также продемонстрирует несколько примеров быстрых конструкций python.

Citation preview

Page 1: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Быстрые конструкции в python

Page 2: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Циклы

val = 0i = 0while i < 10000: val += i i += 1

from functools import reducereduce(lambda res, x: res+x, range(10000))

val = 0for i in range(10000): val += i

val = 0for i in xrange(10000): val += i

0.415 мс.

744 мс.

0.322 мс.

0.883 мс.

Page 3: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Условия

10 < 10.0

10.0 < 10.0

10 < 10

0.0 + 10

float(10)

Str(10)

"{0}".format(10)

48.5 нс

38.4 нс

26.8 нс

15.8 нс

100 нс

137 нс

116 нс

Page 4: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Список / Словарьa = [i for i in range(100000)]

a = [0]*100000for i in a: a[i] = i

a = []for i in range(100000): a = a + [i]

a = []for i in range(100000): a += [i]

a = []for i in range(100000): a.append(i)

a = []append = a.appendfor i in range(100000): append(i)

8.9 мс

10.2 мс

37000 мс (37 с.)

14.2 мс

8.8 мс

6.03 мс

Page 5: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Список / Словарьwords = ['asjasjd', 'akaksd', 'ajskskd', 'kasald']

a = {}for word in words: if word not in a: a[word] = 0 a[word] += 1

a = {}for word in words: try: a[word] += 1 except KeyError: a[word] = 1

a = {}get = a.getfor word in words: a[word] = get(word, 0) + 1

852 нс

1600 нс

681 нс

Page 6: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Арифметические операции

pow(3, 30)

3 ** 30

math.sqrt(144)

144 ** .5

k = 1000

k >> 1

k / 2

k << 1

k * 2

189 нс

16.2 нс

68.3 нс

15.8 нс

39 нс

38 нс

50.3 нс

52.3 нс

65.6 нс

49.9 нс

68.8 нс

45.1 нс

Python 2 Python 3

Page 7: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Строкиstr1 = 'val1'str2 = 'val2'str3 = 'val3'

'str1: {} str2: {} str3: {}'.format(str1, str2, str3)

"".join(['str1: ', str1, 'str2: ', str2, 'str3: ', str3])

'str1: ' + str1 + ' str2: ' + str2 + ' str3: ' + str3

'str1: %s str2: %s str3: %s' % (str1, str2, str3)

'str1: {0} str2: {1} str3: {2}'.format(str1, str2, str3)

a = ['str1: ', str1, 'str2: ', str2, 'str3: ', str3] "".join(a)

s = 'trashtrashtrashtrashabrakadabratrash'

if s.find('abra') != -1 : pass

if 'abra' in s : pass

299 нс

284 нс

243 нс

235 нс

192 нс

152 нс

162 нс

44.3 нс

Page 8: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Python медленный ?

Page 9: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Пример задачи

Задан массив чисел. И поступила n запросов найти сумму от l до r.

Очевидный вариант:

s = 0 for i in range(l, r+1): s += a[i]

Продвинутый вариант:

sum(a[l:r+1])

Тест: 10000 элементов, n = 10

0.49 сек.

0.224 сек.

Page 10: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Написать быструю структуру данных (Дерево отрезков):

Page 11: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

class Tree(): def __init__(self, a): self.a = a self.t = [0] * len(a)*4 self.build_tree(1, 0, len(self.a)-1)

def build_tree(self, v, l, r): if l == r: self.t[v] = self.a[l] return self.t[v] mid = (l+r) // 2 self.t[v] = self.build_tree(v*2, l, mid) + self.build_tree(v*2+1, mid+1, r) return self.t[v]

def slice(self, v, l, r, tl, tr): if l == tl and r == tr: return self.t[v]

mid = (l+r) // 2 if tl >= l and tr <= mid: return self.slice(v*2, l, mid, tl, tr) if tl >= mid+1 and tr <= r: return self.slice(v*2+1, mid+1, r, tl, tr)

return self.slice(v*2, l, mid, tl, mid) + self.slice(v*2+1, mid+1, r, mid+1, tr)

0.1 сек.

Page 12: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Пример задачи

Посчитать N-ое число Фибоначчи. (1, 1, 2, 3, 5, 8, 13 …. )

def fib(n): a = 0 b = 1 for i in xrange(n): a, b = b, a+b return a

def fib2(n): matrix = [[1, 1], [1, 0]] return bin_pow(matrix, n+1)[1][1]

370 мс.

43.4 мс.

При n = 3000 При n = 10^7

25 мин.

89 мс.

Page 13: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

cpmoptimize

from cpmoptimize import cpmoptimize

@cpmoptimize()def fib(n): a = 0 b = 1 for i in xrange(n): a, b = b, a+b return a

При n = 3000 При n = 10^7

368 мс. 13 сeк.

Page 14: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

cpmoptimize

cpmoptimize.xrange(start, stop[, step])

cpmoptimize.cpmoptimize(strict=False, iters_limit=5000, types=(int, long), opt_min_rows=True, opt_clear_stack=True)

Плюсы:

- ускоряет работу программы- поддерживает большие типы данных- легкий в использовании- заботится о памяти

Минусы:

- оптимизирует только если все константы и переменные, используемые в нём, имеют допустимый тип- Тело цикла должно состоять только из инструкций присваивания, унарных и бинарных операций- Не может содержать условий, вызовов других функций, операторов return и yield

Page 15: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Другие методы ускорения

1) PyPy — альтернативный интерпретатор Python с поддержкой JIT-компиляции

2) Pyston — новый альтернативный интерпретатор Python, транслирующий код в промежуточное представление LLVM

3) Nuitka — компилятор Python. Умеет создавать exe файлы

4) astoptimizer — библиотека, применяющая известные методы оптимизации перед компиляцией в байт-код путём анализа и изменения абстрактного синтаксического дерева.

5) foldy.py — библиотека, анализирующая байт-код и выполняющая сворачивание констант а также удаление неиспользуемых функций

6) Numba — библиотека, ускоряющая программы, содержащие математические вычисления и операции с массивами. Оптимизация происходит за счёт JIT-компиляции

7) Cython — оптимизирующий компилятор надмножества языка Python, позволяющий использовать в программе статическую типизацию и тесно взаимодействовать с кодом на C и C++.

Page 16: Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014

Вывод

1) Если что-то можно заменить на встроенные функции – надо менять, т.к. VM довольно медленная.

2) Будьте внимательны к типам, так как из-за них можно потерять скорость в 2-4 раза

3) Меньше глобальных переменных

4) Придумывайте алгоритмы

5) Если не смогли придумать пользуйтесь оптимизациями