Table of Contents

python_speed

Python существует уже много лет и за всё это время Гвидо ван Россум и другие разработчики этого языка стремились к созданию чистого дизайна языка. Для этого нужно было описать язык его же терминами. И по понятным причинам интерпретаторы на C(Cpython - самая популярная и на данный момент эталонная реализация) , Java(Jython) , на стеке .NET(IronPython)не подходят. Собственно нужна была реализация на самом питоне. И тут миру явился PyPy.

Проект PyPy реализован не на самом python , как это может показаться на первый взгляд, а на его подмножестве rPython. По своей задумке PyPy можно назвать средой исполнения к которой можно подключать любой другой язык. К примеру для повышения производительности можно создавать эффективные и низкоуровневые оптимизаторы, средством JIT(just in time compilation). Данная технология используется не только в питоне, но и в Java.

Однако в этой статье я бы хотел поговорить не о самом PyPy, а о том на чём непосредственно написан PyPy - подмножестве rPython. И не смотря на всего его преимущества, понять и начать работать с rPython не так уж и просто. По тому давайте рассмотрим пару примеров.

Cтатическая типизация

Type_py

Не смотря на то, что с python я столкнулся раньше других языков. На статическую типизацию я впервые обратил внимание в TypeScript - расширении языка JavaScript для работы со статически типизированными данными. Но тем не менее давайте перейдём к нашему основному пациенту.

Основной код пишем в теле главной функции, остальные функции пишем вне тела.

def main(argv):
  #пиши весь код сюда
  return 0

def target(*args):
  return main, None

if __name__ == '__main__':
  import sys
  main(sys.argv)

Cкомпилировать код можно после установки PyPy:

cd Downloads/
wget https://bitbucket.org/pypy/pypy/downloads/pypy-1.6-linux.tar.bz2
cd ../.local
tar jxvf ~/Downloads/pypy-1.6-linux.tar.bz2
ln -s ~/.local/pypy-1.6/bin/pypy ~/.local/bin/

Возможно ставить пакеты таким образом несколько не рационально, но я поставил их именно так. Но никто не мешает вам устанавливать любым другим способом.

Затем желательно установить pip, если он еще не инсталлирован у вас в системе.

Как опцию, можно использовать и виртуальное окружение venv, но в маленьких и простых примерах кода я считаю это неуместным. Однако в чём-то крупном я бы его задействовал.

Давайте напишем простую функцию по подсчёту чисел.

#Функция
def add(x,y):
  return x + y
  
print add(1,2)

Однако если мы подставим данные неправильного типа(‘сat’,‘dog’), то получим ошибку:

[translation:ERROR] In <FunctionGraph of (rptest:9)main at 0x103f7dc58>:
[translation:ERROR] Happened at file rptest.py line 11
[translation:ERROR]
[translation:ERROR]       print add(1,2)
[translation:ERROR] ==>   print add('cat','dog')

Затем удалив add(1,2), снова произойдёт компиляция. Это происходит потому, что rPython генерирует статически типизированные данные на лету, но если введённые данные отличаются от ожидаемых, то компилятор выведет вам ошибку.

Совет: Запоминай и правильно используй типы данных

Функции

Многие стандартные функции представленные в стандартной реализации могут не работать в rPython.

'bird'.split()#Работать в rPython не будет

А вот:

'bird'.split('')#Будет работать в rPython

А что на счёт лямбды?

py_lambda К сожалению или к счастью лямбды в rPython работать не будут. В место них нужно использовать классические функции.

def map(fun,ls):
  nls = []
  for l in ls:
    nls.append(fun(l))
  return nls
  
def add_one(x):
  return x + 1

map(add_one, [1,2,3])

Операторы

operator_py Следует внимательно работать в этой реализации и с операторами.

def hello()
  return 'hi'

hello() == None

Если запустить этот код,то всё это дело завершиться ошибкой: *MissingRTypeOperation: unimplemented operation: ‘eq’ on (, )

Вы можете исправить эту ошибку заменив конструкцию == на is.

Грамотная работа с rPython

Думаю,что многих заинтересует rPython. И не важна причина, будь-то статическая типизация данных или быстрая скорость работы. Тем не менее стоит тщательно подготовиться к работе с данным инструментом, для того чтобы писать валидный код. Для себя я составил простой план, согласно которому довольно легко написать что-то годное:

  • Написать код на стандартном питонe

  • Отладить его

  • Скомпилировать код в rPython

  • Произвести отладку согласно требованиям rPython

  • Финальная проверка

Совет: Сначала проверь работу в Python, перед тем как материть этот чёртов rPython.

Cахарочку не желаете?

sugar_py

Думаю, что кто-то может назвать rPython проектом , привносящим синтаксический сахар. Утверждение спорное, однако некоторые вещи действительно выглядят более дружелюбно в *R реализации.

return (x < y) if hasattr(x, '__lt__') 
else (not y <= x) #python

А вот более дружелюбная версия на rPython :

return x.heur() < y.heur() #rPython

Бенчмарки

Согласно бенчмаркам PyPy действительно быстрее стандатного змея.

bench

Заключение

RPython действительно интересная вещь. Питон любят за его простоту, обилие библиотек на любой вкус и цвет. Но не любят за его медлительность. Да, в большинстве случаев вам эта ошеломляющая скорость и не нужна, но есть те сферы где она просто необходима. И эту проблему призван решить rPython. Пускай он не так и прост, пускай многое придётся адаптировать. Однако я считаю, что оно окупится, если на то есть необходимость. Но не одним rPython’ом единым. Есть еще одна быстрая реализация python, и имя ей - stackless….