Запуск функции по окончанию каждого календарного месяца python
Проблема в том, что в разных месяцах разное количество дней, а функцию требуется запускать по окончании календарного месяца. Первое, что приходит в голову, это записать словарь с названием месяца и количеством дней в нем, а затем сверяться с ним в бесконечном цикле. Но уверен есть более простые и грамотные решения задачи. В идеале без обращения к каким-либо веб сервисам. При этом важно, чтоб запуск функции производился вовремя, даже при условии перезапуска скрипта на протяжении месяца
def event(): pass
Что придет в голову

— В чем дело? — спросили гномы и разом обернулись к нему, а он, не в силах совладать с собой, воскликнул:
— Послушайте, что я скажу!
— Мне кажется, вам надо пойти на Восток и на месте выяснить, что и как. В конце концов, существует Боковой Вход, и драконы когда-нибудь да спят, и, если посидеть у входа подольше, что-нибудь непременно придет в голову.
Напишите программу, которая определит, есть ли в строках что-нибудь стоящее. А стоящее – это если в строке есть туннель в любой форме (достаточно проверить туннел) или то слово, которое будет введено первым.
Формат ввода
Вводится строка – слово для проверки.
Затем вводится число – количество строк, а затем сами строки.
Формат вывода
Если количество стоящих строк не менее трех, то вывести МЫСЛЬ ЕСТЬ! Иначе вывести ПОСИДИМ ЕЩЕ.
Затем вывести процентное отношение неподходящих строк к их общему количеству.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Что будет если на сервер придет одновременно два запроса?
Доброго дня!) Вопрос теоретический, но все же. Смотрите например есть форма куда забиваются данные.
Название для youtube канала, предлагайте все, что придет вам в голову.) (Тематика: Юмор, Приколы)
Мне нужно название для youtube канала, предлагайте все, что придет вам в голову.) (Тематика: Юмор.
Что с большей вероятностью придет раньше: автобус или маршрутка?
Автобус приходит на остановку каждые 15 минут, а маршрутка — каждые 10 минут. Известно, что.
Найти вероятность того, что хотя бы одно письмо придет по адресу
Написали m писем, перемешав которые, подписали случайным образом и отправили n друзьям. Найти.
Регистрация: 21.11.2021
Сообщений: 1
word = input()
numb = int(input())
count = 0
for i in range(numb):
text = input()
if ‘туннел’ in text:
count += 1
if word in text:
count += 1
count = numb — count
count = (count / numb) * 100
if count >= 3:
print(‘МЫСЛЬ ЕСТЬ!’, count, sep=’\n’)
else:
print(‘ПОСИДИМ ЕЩЕ’, count, sep=’\n’)
Регистрация: 22.03.2022
Сообщений: 7
Мне приняли (От Фэшиара)
1 2 3 4 5 6 7 8 9 10 11 12 13
z = input() x = int(input()) count = 0 for i in range(x): c = input() if 'туннел' in c or z in c: count += 1 counter = (100 / x) * (x - count) counter = str(counter)[:-1] if count >= 3: print('МЫСЛЬ ЕСТЬ!', counter, sep='\n') else: print('ПОСИДИМ ЕЩЕ', counter, sep='\n')
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Определить вероятность того, что за три текущие минуты в отдел заказов придёт хотя бы один клиент
В отдел заказов в среднем приходит 12 клиентов в час. Определить вероятность того, что за три.
Определить вероятность того, что в порт в день придет 2 судна, 4 судна
В порт в среднем проходит 3 судна вдень.Какая вероятность того, что в порт в день придет 2 судна, 4.
Что делать с header? Ломаю голову
Дело в том, что я использую блоки. Вот главный файл через который выполняется вся робота buy.php .
Сломал голову. а что за ошибка — не пойму
Подскажите пож-та, о чем говорит эта ошибка: MySQL result resource in.
Схватил вирус, пробовал все что в голову пришло
Здравствуйте, столкнулся с такой проблемой. Последнюю неделю пк начал тормозить, сначала не придал.
Что такое обертка и фреймворк? Можно на примерах? В голову не лезет
Я все таки с трудом понимаю что такое фреймворк. Так же я опять забыл что такое обертка. Можно.
Или воспользуйтесь поиском по форуму:
Рекурсия — Python: Функции
В этом уроке мы узнаем, что такое рекурсия, зачем она нужна и чем отличается рекурсия в математике и в языках программирования. Еще мы разберем условие завершения рекурсии и обсудим, какие виды рекурсии существуют.
Что такое рекурсия
Рекурсия в программировании — это возможность дать определение функции, используя в процессе саму определяемую функцию. В математике многие функции определены именно таким образом, поэтому и большинство языков программирования используют этот подход.
Это работает и в Python. Обычно в определении функции можно использовать только определения, которые дали ранее. Но есть одно исключение — функция в своем теле может вызывать себя. Выглядит это так:
def factorial(n): if n 0: return 1 return n * factorial(n - 1)
Интерактивный пример: https://replit.com/@hexlet/python-functions-recursion-factorial#main.py
Эта функция вычисляет факториал числа n через умножение числа на факториал числа n — 1 .
Условие завершения рекурсии
В примере выше используется условие, которое прекращает рекурсию. Если в этой функции убрать условие, которое проверяет аргумент на неотрицательность, то первый же вызов этой функции заставит программу зациклиться — функция продолжит вызывать себя постоянно.
В определениях рекурсивных функций практически всегда есть подобное условие. Оно позволяет вычислению пойти по одной из веток:
- По рекурсивной — в этой ветке произойдет вызов себя
- По терминальной — закончит вычисление и вернет результат
Какой-то из аргументов рекурсивной функции должен обязательно убывать. В качестве убывания может быть:
- Уменьшение счетчика
- Отбрасывание головы списка при движении к его хвосту
- Вызов себя для части исходной структуры при обработке древовидных структур данных
Чтобы понять, что программа не зациклится, используют метод «пристального взгляда» и тесты. Особенно важно проверять срабатывание условия завершения рекурсии.
Переполнение стека
В большинстве программ, написанных на поддерживающих вызов функции языках, этот вызов устроен так: перед вызовом функции текущее место в программе запоминается в стеке. А когда функция возвращает результат, то соответствующий элемент стека отбрасывается.
Стек (stack) — это абстрактный тип данных, который похож на стопку монет. Монета, которую положили последней, будет снята первой. И при снятии монет порядок получается обратным порядку складывания.
В этом же стеке сохраняются значения аргументов функции, а иногда и другая служебная информация. При этом память, которая выделяется для стека при запуске программы, конечна и ограничена.
Если функция будет вызывать себя постоянно и не возвращать результат, то память в итоге закончится. Когда заканчивается память, выделенная для стека вызовов, стек переполняется.
В итоге мы не сможем посчитать факториал для достаточно больших чисел с помощью рекурсивной функции. Но сможем посчитать с помощью итеративной — написанной с использованием циклов и переменных.
Так выглядит переполнение стека при подсчете факториала:
factorial(1000) # Traceback (most recent call last): # File "", line 1, in # File "", line 4, in factorial # File "", line 4, in factorial # File "", line 4, in factorial # [Previous line repeated 995 more times] # File "", line 2, in factorial # RecursionError: maximum recursion depth exceeded in comparison
Сообщение говорит, что превышена максимальная глубина рекурсии. Глубиной рекурсии называется количество последовательных вызовов себя без возврата значения. В Python максимальная длина искусственно ограничена, потому что проще считать количество вызовов, чем предсказывать окончание памяти.
Зачем нужна рекурсия
Некоторые алгоритмы реализуются проще, если использовать именно рекурсию, а не циклы. Часто такие алгоритмы работают с рекурсивными структурами данных — деревьями, «словарями словарей словарей» и подобными. При реализации таких алгоритмов нужно помнить, что память для стека конечна. При этом обычно конечны и сами обрабатываемые структуры данных, поэтому отказываться полностью от рекурсии не стоит.
Виды рекурсии
Рекурсии можно разделить на два вида по тому, как они себя вызывают:
- Прямая — когда функция вызывает себя
- Косвенная — когда одна функция внутри себя вызывает другую функцию, которая когда-то вызовет первую
Так же рекурсии можно разделить по количеству рекурсивных вызовов:
- Линейная — когда при вычислении результата функции функция вызывает себя один раз, как в примере с factorial . Уточним, что «один раз» — это не про общее количество вызовов функции в теле. Речь идет о количестве вызовов, результаты которых нужны для одного общего вычисления
- Каскадная — когда функция вызывает себя несколько раз
Рассмотрим подробнее линейную и каскадную рекурсию.
Пример линейной рекурсии
Если рекурсия в функции проверяет Гипотезу Коллатца , она считается линейной:
def collatz(n): if n == 1: return True if n % 2 == 0: return collatz(n // 2) return collatz(n * 3 + 1)
Интерактивный пример: https://replit.com/@hexlet/python-functions-recursion-collatz#main.py
Здесь в теле функции есть два рекурсивных вызова, но в каждом заходе используется только один.
Еще один пример использования линейной рекурсии — обход коллекций. Для этого можно рекурсивно представить коллекцию как:
- Начало (голову)
- Остальную часть коллекции (хвост)
Дальше хвост также можно разложить на голову и новый хвост. И так до тех пор, пока не останется голова и пустой хвост:
[1, [2, 3]] -> [1, [2, [3]]] -> [1, [2, [3, []]]]
При рекурсивной обработке коллекции мы будем обходить коллекцию и дробить старый хвост на новую голову и новый хвост на каждой итерации. Так мы делаем до тех пор, пока не получим пустой хвост — то есть конец коллекции:
# Функция рекурсивно обходит список, суммируя числа из него def sum(array): # Мы можем использовать оператор упаковки для записи в хвост остальной части списка head, *tail = array if not tail: return head return head + sum(tail)
Пример каскадной рекурсии
Если рекурсия в функции вычисляет очередное Число Фибоначчи , она называется каскадной:
def fibonacci(n): if n 2: return 1 return fibonacci(n - 1) + fibonacci(n - 2)
Интерактивный пример: https://replit.com/@hexlet/python-functions-recursion-fibonacci#main.py
Здесь функция всегда вызывает себя два раза. Сначала будет два вызова, которые превратятся в четыре — два раза по два вызова. Затем в восемь — количество вызовов растет каскадно.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Используйте Psyco, и Python будет работать так же быстро, как и С
В некоторых отношениях дизайн Python напоминает дизайн Java. Оба используют виртуальную машину, которая интерпретирует псевдотранслируемый байткод. Область, в которой виртуальная машина Java обошла Python — это оптимизация выполнения байткода. Psyco, компилятор обработки Python, помогает «сравнять счет». Сейчас Psyco — это внешний модуль, но когда-нибудь он может быть включен в сам Python. Совсем чуть-чуть дополнительного программирования, и Psyco можно использовать, чтобы на порядок ускорить код Python. В этой статье Дэвид рассматривает, что есть Psyco, а также тестирует его в некоторых приложениях.
Обычно Python достаточно быстро делает то, что вы хотите. Девяносто процентов вопросов, которые возникают у начинающих программистов касательно скорости исполнения интерпретируемых/ байткомпилируемых языков, подобных Python, просто наивны. На современных аппаратных средствах большинство неоптимизированных программ Python исполняются так быстро, как от них требуется, и в действительности нет никакого смысла тратить дополнительные усилия на программирование, чтобы приложение работало быстрее.
В этой статье, следовательно, я коснусь только оставшихся десяти процентов. Время от времени программы на Python (или программы на других языках программирования) выполняются недопустимо медленно. Решаемые вопросы могут быть самыми разными; редко требуется выигрыш в миллисекунды, но ускорение задач, которые выполняются в течение минут, часов, дней или недель часто стоит усилий. Более того, необходимо заметить, что не все, что работает медленно, вызвано центральным процессором. Если, например, на выполнение запроса к базе данных требуются часы, не имеет особого значения, обрабатывается ли результирующий набор данных в течение минуты или двух. Эта статья также и не о проблемах ввода/вывода.
Существует несколько способов ускорить программы на Python. Первое, что должно прийти в голову любому программисту, — это улучшить алгоритмы или используемые структуры данных. Микрооптимизация шагов неумелого алгоритма -удел глупцов. Например, если порядок сложности текущей технологии O(n**2), десятикратное ускорение шагов гораздо менее полезно, чем нахождение замены O(n). Это правило применимо даже при рассмотрении такого исключительного подхода, как перепрограммирование на ассемблере: правильный алгоритм на Python часто будет выполняться быстрее, чем неверный алгоритм, переложенный вручную на ассемблер.
Вторая технология, которую вы должны рассмотреть в первую очередь — это профилирование своего приложения Python с позиции перепрограммирования ключевых частей в виде модулей расширения на С. Используя обертку расширений, как, например, SWIG (см. Ресурсы), вы можете создать расширение С, которое выполняет в виде кода на С элементы вашей программы, которые поглощают больше всего времени. Такое расширение Python относительно просто, но требует некоторого времени на освоение (и знания С). Вы увидите, что очень часто львиная доля времени, отводимого на выполнение вашего приложения на Python, затрачивается на горстку функций, и поэтому возможен значительный выигрыш.
Третья технология основывается на второй. Грэг Эуинг (Greg Ewing) создал язык Pyrex, который соединяет Python и С. В частности, чтобы воспользоваться Pyrex, вы пишете функции на схожем с Python языке, который добавляет к выбранным переменным объявления типов. Pyrex (средство) преобразует pyx-файлы в расширения «.с». После трансляции компилятором С, эти модули Pyrex (язык) могут быть импортированы и использованы в ваших обычных приложениях Python. Поскольку Pyrex использует практически такой же синтаксис, как и сам Python (включая директивы цикла, ветви и исключения, формы присвоения [assignment forms], структурированное расположение и так далее), программисту на Pyrex не нужно изучать С, чтобы писать расширения. Более того, Pyrex допускает более цельное — по сравнению с расширением, написанным непосредственно на С — смешение переменных уровня С с переменными уровня Python в пределах одного и того же кода.
Тема данной статьи — еще одна технология. Модуль расширения Psyco может встраиваться в самые недра интерпретатора Python и выборочно заменять части интерпретируемого байткода Python оптимизированным машинным кодом. В отличие от описанных выше методик, Psyco работает исключительно во время исполнения Python. Другими словами, исходный код Python транслируется командой python в байткод точно так же, как и раньше (за исключением пары директив import и вызовов функций, добавленных для запуска Psyco). Однако, пока интерпретатор Python выполняет приложение, Psyco иногда делает проверки, чтобы выяснить, может ли он заменить обычные операции байткода Python на некоторый обработанный машинный код. Эта обрабатываемая трансляция не только очень похожа на то, что делает компиляция по месту (just-in-time compilers) Java (по крайней мере, в широком смысле), но и зависит от архитектуры. В настоящее время, Psyco доступен только для архитектур с процессором i386. Прелесть Psyco заключается в том, что вы можете использовать тот же самый код Python, который вы писали всё это время (буквально!), но исполнять его быстрее.
Как Psyco работает
Чтобы полностью понять Psyco, вам, вероятно, потребуется хорошо разбираться и в функции eval_frame() интерпретатора Python, и в ассемблере i386. К сожалению, сам я не могу претендовать на роль эксперта, но думаю, что смогу объяснить Psyco в общих чертах, не допуская слишком серьезных ошибок.
В обычном Python функция eval_frame() — это внутренний цикл интерпретатора Python. В основном, функция eval_frame() смотрит на текущий байткод в контексте выполнения и переключает управление в функцию, подходящую для реализации этого байткода. Специфика того, что эта функция поддержки будет делать, зависит, в общем, от состояния различных объектов Python, находящихся в памяти. Поясним — суммирование объектов Python «2» и «3» приводит к результату, отличному от суммирования объектов «5» и «6», хотя обе операции обрабатываются одинаково.
Psyco заменяет функцию eval_frame() составным оценочным модулем. Существует несколько способов, позволяющих Psyco улучшить то, что делает Python. Во-первых, Psyco транслирует операции в до некоторой степени оптимизированной машинный код; само по себе это приводит только к незначительным улучшениям, поскольку то, что машинный код должен выполнить, — это то же самое, что делают обработанные функции Python. Более того, то, что является «обработанным» в трансляции Psyco, это больше, чем выбор байткода Python, Psyco также уточняет значения переменных, которые известны в контексте выполнения. Например, в коде, аналогичном приведенному ниже, переменная x распознаваема на протяжении цикла:
x = 5
l = []
for i in range(1000):
l.append(x*i)
Оптимизированной версии этого кода не нужно умножать каждый i на «содержимое переменной/объекта x» — менее расточительно просто умножать каждый i на 5, исключая тем самым поиск/косвенную ссылку.
Помимо создания кода, предназначенного для i386, для небольших операций, Psyco кеширует этот транслированный машинный код для дальнейшего использования. Если Psyco способен установить, что отдельная операция такая же, как выполненная (и «обработанная») ранее, он может положиться на этот кэшированный код, а не транслировать этот сегмент. Это экономит еще немного времени.
Реальная экономия в Psyco, однако, является результатом распределения операций по трем различным уровням. Для Psyco существуют переменные «времени исполнения («run-time»), «времени трансляции» («compile-time») и «виртуального времени» («virtual-time»). При необходимости Psyco перемещает переменные с одного уровня на другой. Переменные времени исполнения — это просто исходный байткод и структуры объекта, которые обрабатывает обычный интерпретатор Python. Переменные времени трансляции отображаются в машинные регистры и ячейки памяти с прямым доступом, как только Psyco транслирует эти операции в машинный код.
Наиболее интересный уровень — это переменные виртуального времени. Изнутри переменная Python — это полная структура с множеством членов — даже если объект представляет всего лишь целое число. Переменные виртуального времени Psyco представляют объекты Python, которые потенциально могут быть построены, если возникнет такая необходимость, но их деталями пренебрегают, пока необходимости нет. Например, рассмотрим следующее присваивание:
x = 15 * (14 + (13 — (12 / 11)))
Стандартный Python строит и разрушает ряд объектов, чтобы вычислить это значение. Целый целочисленный (integer) объект создается для того, чтобы содержать значение (12/11) ; затем значение извлекается из структуры этого временного объекта и используется для вычисления нового временного объекта (13-PyInt) . Psyco пропускает эти объекты и просто вычисляет значения, зная, что «при необходимости» объект может быть создан из этого значения.
Используя Psyco
Гораздо легче использовать Psyco, чем его объяснять. В основном, все, что нужно, — это сказать Psyco какую функцию/метод «обрабатывать». Не надо менять код ни одной из ваших функций Python, ни сами классы.
Существует пара подходов, предназначенных для указания, что Psyco должен делать. «Бронебойный» подход — это разрешить Psyco везде выполнять операцию компиляции по месту. Чтобы сделать это, поместите следующие строки кода в начале вашего модуля:
import psyco ; psyco.jit()
from psyco.classes import *
Первая строка указывает Psyco применить свою магию ко всем глобальным функциям. Вторая строка (для Python 2.2 и выше) приказывает Psyco сделать то же самое с методами класса. Чтобы немного точнее направить поведение Psyco, вы можете воспользоваться командой:
psyco.bind(somefunc) # or method, class
newname = psyco.proxy(func)
Вторая форма оставляет func в качестве стандартной функции Python, но оптимизирует вызовы, которые задействуют newname . Практически во всех случаях, кроме тестирования и отладки, форма psyco.bind() — это то, что вы будете использовать.
Производительность Psyco
Несмотря на магию Psyco, его использование требует некоторого осмысления и тестирования. Главное, что нужно понять — это то, что Psyco полезен для обработки многократно выполняющиехся циклов, и то, что он знает, как оптимизировать операции, в которых задействованы целые и числа с плавающей запятой. Для нециклических функций и для операций над другими типами объектов Psyco обычно просто добавляет накладные расходы на свой анализ и внутреннюю компиляцию. Более того, для приложений с большим числом функций и классов, включение Psyco для приложения целиком является дополнительным бременем при трансляции машинного кода и использование памяти для этого кэширования. Гораздо лучше выборочно подключить те функции, которые смогут извлечь больше пользы из оптимизации Psyco.
Я начал с самого простого тестирования. Я просто подумал, какое из приложений, которые я недавно запускал, неплохо было бы ускорить. Первый пример, который пришел мне в голову, — это программа манипулирования текстом, которую я использую для преобразования чернового варианта моей будущей книги «Текстовая обработка в Python» (Text Processing in Python) в формат LaTeX. Это приложение использует некоторые строчные методы, некоторые регулярные выражения и некую программную логику, управляемую главным образом регулярными выражениями и совпадениями строк. В действительности это ужасный кандидат для Psyco, но поскольку я его использую, я начал с него.
При первом заходе, все, что я сделал — это добавил psyco.jit() в начало моего скрипта. Достаточно безболезненно. К сожалению, результаты были (как и ожидалось) удручающими. Если первоначально скрипт работал 8.5 секунд, то после «ускорения» с Psyco он выполнялся 12 секунд. Скверно! Я догадался, что компиляция по месту, вероятно, имеет некоторые накладные расходы на запуск, которые затягивают время исполнения. Поэтому следующее, что я сделал, была обработка гораздо более крупного входного файла (состоящего из множества копий первоначального файла). Это привело к крайне скромному успеху — время выполнения сократилось со 120 секунд до 110. Это улучшение оставалось устойчивым при нескольких запусках, но в любом случае весьма незначительным.
Второй заход с моим кандидатом на обработку текста. Вместо добавления вызова psyco.jit() без параметров, я добавил только строку psyco.bind(main) , поскольку функция main() имеет несколько циклов (но минимально использует арифметические операции с целыми числами). В этом случае результаты номинально были лучше. Этот подход урезал время выполнения на несколько десятых секунды для первого примера и на несколько секунд для версии большого входного файла. Но по-прежнему ничего впечатляющего (хотя и никакого вреда).
Для более достойного тестирования Psyco, я откопал некий код нейронной сети, о котором я писал в одной из предыдущих статье (см. Ресурсы). Это приложение «code_recognizer» может быть настроено для опознания возможных распределений разных значений ASCII в различных языках программирования. Нечто подобное потенциально могло бы быть полезно при угадывании типов файла (скажем, потерянных сетевых пакетов); но этот код в действительности полностью универсален в отношении того, чему он был обучен — с таким же успехом он мог бы научиться распознавать лица или звуки, или виды приливов. В любом случае «code_recognizer» базируется на библиотеке Python bpnn, которая в качестве контрольного примера также включена (в модифицированной форме) в дистрибутив Psyco 0.4. Что важно знать о «code_recognizer» в свете этой статьи, так то, что оно вычисляет много циклов с числами с плавающей запятой, и что его выполнение занимает много времени. Вот у нас и появился хороший кандидат для Psyco.
Поэкспериментировав немного, я детально установил, как использовать Psyco. Для этого приложения в случае небольшого количества классов и функций не имеет особого значения, используете вы направленное связывание или по месту. Но лучший результат — на несколько процентов — по-прежнему оказывается за выборочным связыванием классов, которые лучше всего оптимизируются. Более важно, однако, понять область связывания Psyco.
Скрипт «code_recognizer» содержит строки наподобие:
class NN2(NN):
# customized output methods, math core inherited
Другими словами, интересный момент с точки зрения Psyco находится в классе bpnn.NN . Добавление psyco.jit() или psyco.bind(NN2) в скрипт code_recognizer.py мало что дает. Чтобы Psyco выполнял желаемую оптимизацию, вам потребуется добавить psyco.bind(NN) в code_recognizer.py , либо psyco.jit() в bpnn.py . В отличие от того, что вы могли бы предположить, компиляция по месту происходит не при создании экземпляра или вызове методов, а при описании класса. Вдобавок, при подключении производных классов их унаследованные методы не обрабатываются.
Как только были выработаны детали подходящего связывания Psyco, результирующее ускорение оказалось весьма впечатляющим. Используя те же примеры тестирования и режим обучения сети, который был представлен в упомянутой статье (500 шаблонов обучения, 1000 итераций обучения), время обучения нейронной сети было уменьшено с где-то 2000 секунд до приблизительно 600 секунд — больше, чем в три раза. Сокращение числа итераций до 10 показало пропорциональное ускорение (но никуда не годное распознавание нейронной сети) — так же как и промежуточное число итераций.
Я нахожу весьма замечательным ускорение кода, выполнявшегося полчаса, до 10 минут, с помощью двух строк кода. Это ускорение, вероятно, все еще меньше скорости исполнения аналогичного приложения на С, и определенно меньше десятикратного ускорения, которое зарегистрировано в некоторых единичных случаях тестирования Psyco. Но это приложение явно из «реальной жизни», и эти улучшения достаточны для того, чтобы их отметить во многих контекстах.
Куда движется Psyco?
В настоящий момент Psyco не производит статистику или профилирование и выполняет только минимальную оптимизацию генерируемого машинного кода. Возможно, более поздняя версия будет знать, как определять операции, которые могли бы более всего выиграть от оптимизации, и выбрасывать из кеша машинный код для неоптимизируемых операций. Вдобавок, возможно, будущий Psyco мог бы решать выполнять более обширную (но и более дорогую) оптимизацию многократно исполняемых операций. Такой анализ исполнения был бы похож на то, что технология HotSpot компании Sun делает для Java. То обстоятельство, что Java, в отличие от Python, имеет декларации типов, в действительности менее значимо, чем думают многие (однако предшествующие работы по оптимизации Self, Smalltalk, Lisp и Scheme также отмечают это).
Хотя я и сомневаюсь, что это когда-нибудь случится, но было бы здорово, если бы технология типа Psyco была интегрирована в какую-нибудь будущую версию самого Python. Несколько строк для импорта и связываний — не так уж много работы, но тогда Python выполнялся бы существенно быстрее, и изначально это было бы гораздо более цельно. Поживём — увидим.
Ресурсы
- Более подробная информация на домашней странице Psyco и на странице проекта ресурса SourceForge.
- Упрощенная обертка и генератор интерфейса (Simplified Wrapper and Interface Generator, SWIG) — очень широко, и, возможно, повсеместно, используемое средство написания модулей С/С++ для Python и других «скриптовых» языков.
- Грэг Эуинг создал язык Pyrex, который используется для написания модулей расширения Python. Идея Pyrex — определить язык, который, являясь очень близким к самому Python, создает смесь из Python и типов данных С, но который в конечном итоге преобразуется и транслируется в С-расширения Python.
- Язык Vyper Джона Макса Сколлера (John Max Skaller’s) был задуман как улучшенный Python, реализованный на Ocaml. Ожидалось, что будет получена трансляция в тот же самый машинный код, который генерирует Ocaml и который, в общем, сопоставим с быстродействием С. К сожалению, сейчас Vyper — мертвый проект, а версия компилирования так и не была получена. Интервью Дэвида со Сколлером состоялось, когда этот проект еще был живым (developerWorks, октябрь 2000).
- Дэвид в соавторстве с Эндрю Блейзом (Andrew Blais) написали статью Введение в нейронные сети (developerWorks, июль 2001). В ней они привели код, который опирается на модуль Python bpnn, созданный Нилом Шеменойером (Neil Schemenauer). Эта статья использует код нейронной сети, чтобы продемонстрировать возможности Psyco.
- Ряд статей о Linux в зоне Linux developerWorks.
Об авторе
Дэвид Мертц не состоялся ни как охотник, ни как рыбак, ни как пастух. В результате он пришел к критическому критицизму. Возможно, завтра он займется чем-нибудь еще. Дэвид доступен по адресу: mertz@gnosis.cx, а жизнь его описана на http://gnosis.cx/publish/. Присылайте свои замечания и предложения касательно этой, прошлых или будущих статей.
Автор: Дэвид Мертц (David Mertz), нештатный журналист, Gnosis Software Inc.