Обновить
346
Коробов Михаил @kmikeread⁠-⁠only

Пользователь

Отправить сообщение
Да ничего не мешает — в примере (интересном, спасибо!) кусок jit от lua использовали для встраивания jit-компилятора в код на C, теоретически можно было, наверное, из pypy похожий код выдрать (но, наверное, сложнее, отдельно распространяемой библиотеки для генерации ассемблера там вроде нет).

Но согласитесь, написание (и отладка) специализированного jit-компилятора для ускорения конкретного куска кода и вызов sprintf — это задачи совсем разного порядка :)

Ну да, на C, наверное, можно написать версию sprintf, использующую специализированный для sprintf jit-компилятор, и это будет работать, возможно, быстрее, чем pypy (при прочих равных — а они точно будут равными?), но понятно же, что на каждый чих новый jit-компилятор в ассемблер писать никто не будет.
Напишем аналог операции имплементированной на питоне (трансляции некоторых операций сразу в бинарные операции) на си. уверен работать на си это будет ничуть не медленне.


Вы предлагаете на С написать сами операции (прямо в программу зашить спец. версии sprintf для разных аргументов), или написать компилятор, который для sprintf (и любой другой функции) будет уметь генерировать различные варианты компиляции а зависимости от параметров, переданных динамически (например, загруженных из файла?)

Если первое — то это imho не интересно и очевидно.

А вот второе — это то, что делает pypy, и чего не может сделать ни один компилятор C из-за того, что код компилируется не во время выполнения программы, а заранее. В этом-то и суть статьи — показать не теоретически, а на примере (imho даже вполне разумном), который можно «потрогать», что динамическая компиляция может делать то, чего принципиально не может достигать статическая, и из-за этого код на питоне может даже иногда работать быстрее, чем заранее скомпилированный код на C.
По договоренности с Николаем начал потихоньку пилить версию для ленивых:
bitbucket.org/kmike/django-russian-admin

Пока она, правда, для не очень ленивых получается (т.к. пошел путем своего AdminSite), и там еще почти ничего не работает, но кое-что уже есть (см. тестовый проект). План такой: сначала сделать версию для не очень ленивых, а потом, быть может, добавить манкипатчилку для совсем ленивых.

Код можно запаковать в какой-нибудь пакет (django-russian-admin, например). Шаблоны положить в templates и потом в README написать «добавьте russian_admin в INSTALLED_APPS после admin и admin_tools».

Только admin.site.register и admin.site.app_index патчить нехорошо как-то, лучше сделать наследника AdminSite, наверное.
жесть)

Небольшое замечание: пользуйтесь документацией по pymorphy с rtfd ( pymorphy.rtfd.org/), там довольно много всего переписано и, в частности, показан способ, как повторно использовать экземпляр морф. анализатора в случае интеграции с джангой. На packages.pypi.ru неудобно тем, что нужно за ней следить постоянно, и что версия там ровно одна, переехать бы на rtfd полностью, но боюсь, что ссылки кому-нибудь сломаю.

Немного по коду:

1. А вот этот код точно нужен?
form = gram_info['info'][:pos] + u',' + u'ед' if 1 == num else u'мн'


Все методы, принимающие грам. форму, должны это внутри делать (т.е. им нужно передавать не полную грам. форму, а минимальную часть, которая нужно поменять или удостовериться, что полученное слово ей соответствует).

2. Вот тут можете пояснить? Если это какая-то штука, которая всегда должна быть такой, может имеет смысл ее прямо в pymorphy включить и в inflect_ru добавить?
if u'КР_ПРИЛ' != info['class']:
    word = morph.pluralize_inflected_ru(word, num).lower()
else:
    word = morph.inflect_ru(word, form, u'КР_ПРИЧАСТИЕ').lower()


3. Там не получится упростить код, воспользовавшись напрямую шаблонными фильтрами? В джанге шаблонные фильтры можно использовать как обычные функции (берут строку, возвращают строку), а фильтры в pymorphy умеют для строк, размеченных [[ ]], части склонять, а части оставлять как есть (+ они сами более-менее сохраняют регистр слов и разбивают текст на слова).
Все иконки публикуются под лицензией Creative Commons Attribution 3.0 (CC BY)


Как хорошо, что это неправда) Там очень много иконок под Public Domain есть.
Только C++ пропустить в этой последовательности, и какой-нибудь функциональщины добавить можно. Ну или просто пройтись по C++ как по C с классами, в детали не вдаваясь. Блин, как я жалею, что на него несколько лет убил, все эти тонкости изучая, которые нигде, кроме C++ не нужны, с какими-то трюками и тонкостями реализации разбираясь вместо разбора алгоритмов и приобретения полезных привычек (вроде KISS, DRY и тестов).
Не смотрел, но в таких случаях обычно внутри лотерея.
Эм, а где она, эта библиотека? Странно же, что ее нет, с учетом того, что на node.js в асинхронном стиле пишут абсолютно все и вопрос стоит очень остро (в отличие от питона, где асинхронные фреймворки занимают лишь небольшую нишу). Ни одной библиотеки не видел на js, которая бы работала с удобством, хотя бы примерно аналогичным adisp. То исключения вручную везде таскать как параметр, то вместо js компиляторы почти-js в js, то какие-то чудные конфигурации вместо вызовов функций. Друг с другом никто не совместим, переход с одной на другую — нетривиальная задача. Бывает, что 1 человек пишет по несколько control flow библиотек. 90% control flow библиотек (которые с год назад расплодились) заглохло, похоже. «Можно сделать библиотеку» поэтому не очень меня убедило. Сомнительно же как-то, что это мол разработчики асинхронного кода на питоне такие умные, а в толпе программистов на node.js все такие глупые. Скорее на js больше с языком бороться нужно, вот и результат. Сделать-то может и можно, но где она, удобная хорошая надежная библиотека без хаков, почему каждые несколько месяцев находится кто-то, кто пишет еще одну (тут вон даже домен зарегали), хорошую на 80%, а не на 100?
Ну строго говоря тут как раз пришлось писать расширение для языка и вводить новые ключевые слова, что говорит как раз не в пользу языка, ведь код на tamejs — это уже не код на js.

Тут ведь никакой экзотики нет — да в том же питоне асинхронный код imho красивее можно организовать, используя тот факт, что через генераторы можно писать сопрограммы (пример для tornado + библиотечки adisp):

@adisp.process
def my_func():
    foo, bar = yield client.get('foo'), client.get('bar')
    baz = yield client.get(foo+bar)
    print baz


foo и bar тут вычислятся параллельно и асинхронно, к строке baz =… управление вернется, когда оба значения будут готовы, ну и baz тоже вычислится асинхронно.

Никаких новых ключевых слов, никаких хаков, работает уже 5 лет как, синтаксис асинхронного вызова практически такой же, как и синхронного, можно возвращать значения и => выполнять команды как для зависимых, так и для независимых функций, ну и с обработкой исключений все в полном порядке (в отличие от tamejs, судя по их сайту).

Мне изначально javascript показался более удобным для асинхронного программирования из-за того, что лямбды можно объявлять сразу, пописал на node, потом по техническим причинам перешел на tornado и оказалось, что асинхронный код в питоне-то писать удобнее, inline-лямбды не нужны. В js все-таки не хватает нормальной поддержки таких фич со стороны языка, оттого все и велосипедят control flow библиотеками разной степени приятности.

Это полезная библиотека, но наличие таких библиотек все-таки не говорит в пользу языка, и это все-таки костыли.
Отличный перевод отличной статьи! В свое время оригинал читал, очень идея понравилась, и то, как все просто сделано — пишем сначала примитивный лексер и парсер для языка (точно так же, как бы мы его и без pypy писали), все работает медленно, потом говорим pypy — «сделай jit» — и pypy после небольших подсказок магически генерирует из нашего парсера jit-компилятор.
Про uniq через set уже сказали — результат-то другой будет, чем в исходном алгоритме.

class Point(object):
	__slots__=('a', 'b', 'c')
	def __init__(self): 
		self.a = None
		self.b = None
		self.c = None

Вместо __slots__ для данного примера в 2.6+ лучше, наверное, использовать namedtuple.

total = sum(int(line.split(',')[5]) for line in open('somefile.csv') if line.split(',')[5])

Этот код полагается на детали реализации сборщика мусора в CPython, лучше так не писать и файлы открывать всегда через with, т.к. в других реализациях (том же pypy) файловый дескриптор останется болтаться.

u'фыва' # строка закодированная в unicode.

Строка в кодировке Unicode. Эта кодировка поддерживает все существующие языки и символы. Выгода, применения такой кодировки, для работы с данными очевидна. Например, для многоязычных приложений.

Принципиальное отличие 'foo' от u'foo' как раз в том, что юникод — это не кодировка.
Offtopic: насчет redis и celery. Как раз вчера с багом разобрался наконец: если используются события, то после первого перезапуска celery-воркеров redis начинает забиваться ненужной ерундой, и с каждым перезапуском скорость забивания возрастает( у меня, например, мегабайт 100 в день было, что для in-memory базы очень критично). Причем, судя по коду, этот баг был всегда, и мне кажется, что у всех, кто использует redis+celery+мониторинг, redis должен быть забит большей частью ненужной ерундой сейчас. По крайней мере, после ручного удаления всего хлама и применения полу-фикса (в комментариях) размер базы с 250M до 2M снизился.

Ask частичный воркэраунд закоммитил (крутой чел, там голову сломать можно), но ни в каких релизах этого пока нет. Так что используйте celery+redis сейчас с осторожностью, а если уже используете, то обновите celery и kombu до последних версий с гитхаба, прочтите внимательно описание бага и посмотрите, не удастся ли уменишьть базу раз эдак в 100, удалив ненужные ключи и перезапустив redis.
В этом смысле pypy рулит, т.к. у него как раз вся информация есть о типах реал-тайм, JIT поэтому же теоретически (и иногда практически) может давать более оптимизированный код и большее ускорение, чем статический компилятор.
Psyco умер, pypy — это «все или ничего» (кусок нельзя ускорить), ускорение через смену алгоритма — это абсолютно правильно, но и так понятно, профайлер — это хорошо.

Но на практике подобные вычисления стоит ускорять через cython или numpy. Не нужно их бояться) Cython не потребует даже переписывать код (можно просто рядом очень небольшой файлик с подсказками положить), numpy переписывать потребует, но, скорее всего, в итоге код короче получится.
Ну да, 2 очереди, io (сеть, диск) параллелить неблокирующими работниками, cpu — процессами, схема замечательная, если бы работала)

Сделал пока тоже 2 очереди (под io-задачи и cpu-задачи), но обе просто на процессах. В cpu-очереди смысла особого нет запускать процессов больше, чем ядер у машины, а вот в io — чем больше, тем лучше.
У меня такое было, если воркер на eventlet или gevent. Точнее, eventlet как-то вообще через раз заводился, а gevent вис под нагрузкой, особенно если в задачах выпадали исключения. Никак в итоге не решил, пока забил (ресурсов сейчас хватает). Видимо, на какой-нибудь торнаде буду отдельно потом неблокирующего работника писать.
add -p всю жизнь был hg record, reflog тоже есть, причем reflog интегрирован в битбакет (форма поиска по репозиторию умеет его синтаксис), rebase не пользуюсь, не знаю, может и нет
При выкатывании изменений просто запускаются тесты на сервере (тем же скриптом, что и локально), никаких инструментов не используется — это тоже CI?
Кстати, когда много таких здач решать приходится, вместо list используют numpy.array, он мощнее и быстрее:

# arr = numpy.array(range(1, 1001))
print arr*2

Информация

В рейтинге
Не участвует
Откуда
Екатеринбург, Свердловская обл., Россия
Работает в
Дата рождения
Зарегистрирован
Активность