Сколько памяти съела программа на Python?
Некоторое время назад мне хотелось выяснить, сколько съедает памяти программа на Python и чем эта память занята. Тогда я не смог быстро найти решение и обошёлся без него, а вчера, совершенно случайно, наткнулся на целых два.
Приведу их у себя полностью, чтобы потом можно было быстро найти.
Следующий код (используется модуль Heapy):
from guppy import hpy
h = hpy()
print h.heap()выведет вот такую, достаточно информативную, табличку:
Partition of a set of 132527 objects. Total size = 8301532 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 35144 27 2140412 26 2140412 26 str
1 38397 29 1309020 16 3449432 42 tuple
2 530 0 739856 9 4189288 50 dict (no owner)Другое решение — использовать Dowser, его интересная особенность — можно наблюдать за работающим кодом через
# memdebug.py
import cherrypy
import dowser
def start(port):
cherrypy.tree.mount(dowser.Root())
cherrypy.config.update({
'environment': 'embedded',
'server.socket_port': port
})
cherrypy.server.quickstart()
cherrypy.engine.start(blocking=False)Подключаем в программу memdebug и вызываем memdebug.start.
Там же упоминается модуль PySizer, но его автор забросил работу и рекомендует использовать Heapy.
IE и rgba
Век живи, век учись. Оказывается, в Internet Explorer есть возможность, через фильтры, указывать
.element{
/*color = black, opacity = 0.6 */
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000,endColorstr=#99000000); /*AARRGGBB*/
zoom: 1
}Большая часть фильтров понимает цвет в формате argb (первая компонента — прозрачность).
Web Standards Days
27 и 28 ноября (может и на выходные останусь, как срастётся) еду в Минск на «Web Standards Days».
В Казань
Вылетаю сегодня (3 ноября) в Казань, в воскресенье (8 ноября) — назад.
Сколько нужно людей, чтобы получился Chrome
Бобук рассказывает про количество людей, имеющих отношение к появлению Chrome:
Итого, представь себе что 10 миллионов долларов в акциях размазывается между разработчиками проекта. Такие небольшие проекты как Chrome в гугле затрагивают очень небольшую группу, скажем всего
500-600 человек разработчиков,50-100 дизайнеров,200-300 маркетологов, под сотню админов, сотня менеджеров. Итого на нос получается в пике 10 тысяч на лицо. Теперь подумай, что такое в Калифорнии 10 тысяч долларов _В АКЦИЯХ_, т. е. после реализации акций и уплаты налогов — у тебя на руках 5 тыщ долларов.
В ответ на вопрос откуда информация и по поводу численности:
Про команду разработки? Есть некотрые инсайдеры. Не, вообще команда разработки там примерно в 3 раза меньше, но есть же масса людей, которые учавствуют в проекте «парттайм», а доля будет такая же, как и у тех кто работал только над ним.
После недавней фразы Брина «мы ведем исследования небольшими группами
по 200-300 человек», я уже ничему не удивляюсь.
Почти тысяча человек даже в самом минимальном случае!
Компрессоры JavaScript и точка с запятой
Точка с запятой — один байт, перевод строки — один байт. Мне тут подумал, что лучше бы компрессоры JS выкидывали при сжатии не переводы строки, а точки с запятой (там где это возможно, конечно, например, пустой return в некоторых случаях нельзя завершить только переводом строки).
Тогда читаемость кода почти не снижалась бы (об обфускатарах я сейчас не говорю) и можно было бы легко понять где произошла ошибка, пропущенная в production (такое случается).
Полезные rgba в IE
Вадим Макишвили описал несколько примеров применения rgba в Internet Explorer. Примеры очень и очень полезны, и я скопирую их (без картинок, за ними идите в исходный пост) к себе:
Сегодня, благодаря этому новому знанию, я понял как решить две труднорешаемые задачи. Издавна, чтобы сделать фон блока полупрозрачным, мы вынуждены были использовать
или png-24 картинку в фонеили opacity-свойство. Но в случае
с png-24, для ИЕ6 нужно писать AlphaImageLoader фильтр, который катастрофически замедляет рендеринг страницы. А в случае с opacity приходилось придумывать трюки, чтобы дети блока не бледнели от родительского opacity.А теперь проблему opacity можно забыть, как страшный сон: .block { background: #rgba } * html .block { filter:progid:DXImageTransform.Microsoft.gradient (startColorstr=#99000000, endColorstr=#99000000); }
В начальной и конечной позиции один и тот же RGB (000000) и добавляю перед ним одно и то же значение Alpha (99) Значение Alpha указывается
в 16-тиричной системе, где 00 — полностью прозрачный, а ff — непрозрачный пикселЯ протестировал скорость рендеринга страницы, на которой выливается 300 элементов
с gradient-фильтром — он не замедляет рендеринг и это сильно радует.Но этот случай описывает ситуацию, когда нужно сделать однотонный полупрозрачный цвет, как например в модальных диалогах, когда вся остальная страница затемняется.
Иногда использовать
png-24 всё-таки необходимо, как например в случае, когда нужно обрезать длинную неразрывную строку, уводя ее градиентом в непрозрачность.В этом случае можно использовать второй способ. .block { background: url(image.png) } * html .block { filter:progid:DXImageTransform.Microsoft.gradient (startColorstr=#00ffffff, endColorstr=#ffffffff, GradientType=1); }
GradientType принимает значение 1, если градиент рисуется
слева-направо; и 0, если градиентсверху-вниз. MSIE хороший браузер.
Локальные переменные и JS
Читал тут по диагонали стандарт ECMAScript и подумалось мне, что сэмулировать локальные переменные (да, я осознаю, что это свойства объекта) можно вот так:
var a = 10;
with ( { a : 20 }) {
alert(a);
}
alert(a);Ожидаемый результат: сначала код выведет «20», потом — «10». Я ещё не задумывался над тем насколько это практично и изящно, просто придумалось.
Кстати, обратите внимание, что следующий код выведет «30», «30», «10», «30»:
var a = 10, b = 10;
with ({a:20}) {
var a = 30, b = 30;
alert(a);
alert(b);
}
alert(a);
alert(b);Добавлено 10 ноября 10:55: в комментариях
Ягоды

Вчера жена домой заманивала, чтобы я пришёл пораньше с работы — купила клубники, выложила на тарелке и прислала мне фотографию.
Попытка пересесть на Firefox. 2:0 в пользу «Оперы»
Посмотрел Firefox 3.6 beta 2, что сподвигло меня на очередную попытку пересесть на этот браузер с «Оперы»: скорость работы уже приблизилась к комфортной. Пересесть на Firefox хочется, прежде всего,
Неделю попользовался Firefox, не осилил. Нехватает тысячи мелочей, некоторые из которых не правятся плагинами. Например, почему при нажатии кнопки «Назад» в браузере, Firefox не показывает документ в том месте, где я остановил чтение? Мне что, на каждый чих закладку открывать?
Таких мелочей — очень много, слишком много, чтобы я мог спокойно пользоваться браузером. Приводить их полный список смысла нет, если даже многие их них правятся плагинами, я не готов тратить своё время, чтобы точить браузер под себя. И потом, чем больше плагинов, тем он больше тормозит.
Придётся, как и раньше, жить в двух программах. Это, кстати, моя вторая попытка переползти на Firefox.
Flash и безопасность
В качестве вялых воскресных препирательств, на «Хабре»
Между тем, правил для защиты от таких «уязвимостей» всего два: выдавать при обращении к заливаемым пользователем Flash заголовки для скачивания (а то и вообще отдавать все пользовательские ролики с другого домена, порта или протокола) и указывать правильные параметры для проигрываемых роликов, залитых пользователем. Последнее — нехитрая наука, таких параметров всего три: allowScriptAccess, allowNetworking и allowFullScreen.
Их назначение легко расшифровывается по названию.
Параметр allowScriptAccess (введен во Flash 6.0.40.0) управляет доступом к JavaScript/DOM браузера и имеет три возможных значения: always, sameDomain и never. Пояснения, на мой взгляд, требует только значение sameDomain. Если выбрано это значение, то доступ предоставляется только скриптам, которые загружены с того же домена, что и страница, куда они подключены.
Следующий параметр, allowNetworking (работает, начиная с Flash 9.0) разрешает или запрещает обращение Flash к собственным сетевым функциям и сетевым функциям браузера. Имеет значения all, internal (запрещает использование сетевых функций браузера) и none.
Параметр allowFullScreen (Flash 9 и выше) принимает два возможных значения — false (выставлено по умолчанию) или true, которые (соотвественно) запрещают или разрешают использование полноэкранного режима.
Очевидно, что наиболее безопасные параметры — allowScriptAccess="never", allowNetworking="none" и allowFullScreen="false":
<object height="400" width="500">
<param name="allowScriptAccess" value="never" />
<param name="allowNetworking" value="none" />
<param name="movie" value="ролик.swf" />
<embed type="application/x-shockwave-flash"
allowScriptAccess="never" allowNetworking="none" src="ролик.swf" height="400" width="500" />
</object>Очень жаль, но значение «never» для параметра для параметра «allowScriptAccess» сейчас является deprecated, так же как и использование параметра allowNetworking, когда страница, на которой подключен ролик и сам ролик загружаются с одного и того же домена.
Насколько я понимаю, это связано с тем, что фирма Adobe, текущий владелец технологии Flash, не хочет брать на себя ответственно за утечку критичных данных через Flash-ролики. Вместо использования этих значений параметров рекомендуется загружать Flash-ролики с другого домена и не допускать того, чтобы критичные данные и ролики были доступны с одного домена.
Уу-и-и-и-и

Благодаря Паше Катурову и магазину «33 dodo» (кстати, жена, посмотри какие там наклейки в свою квартиру, сегодня будем смотреть и плакать вместе) теперь у меня на столе летают весёлые оранжевые самолётики.
IE9
В блоге Microsoft, посвящённом их браузеру появилась статья об Internet Explorer 9. То, что есть сейчас уже очень неплохо — IE9 по скорости (если верить данным Microsoft) лишь
Internet Explorer 9.0 проходит тест селекторов CSS3 с результатом 574 из 578 (IE8 — 330/578), тест ACID3 — 32% (IE8 — 20%), поддерживает
Не могу поверить, что этот движок и есть «Газель» о которой говорили ранее, ведь «Газель» имела большие проблемы с производительностью, да и в статье из блога о безопасности и изоляции вкладок (основные фишки «Газели») ни слова.
P.S. Кстати, если покопаться, то можно найти как выглядит
Движок, как видим, всё ещё называется «Trident», хотя номер смущает — 4.0, как мы знаем, версия, которая входит в IE8.
Олимпийка
Ехал сегодня в метро, от нечего делать разглядывал пассажиров (забыл новую книгу загузить в телефон), случайно обратил внимание на дедушку, у него под полурасстёгнутом пальто, виднелась олимпийка. Помните такую? Как новая, а ведь ей лет 20.
Я много лет, с самого детства не слышал этого слова, не вспоминал, но стоило увидеть характерного василькового цвета «олимпийскую» кофту с молнией на горле, и оно мгновенно пришло на ум. Я сейчас поискал в «Яндексе», оказывается олимпийки до сих пор продаются (например «Адидас» их выпускает), но у меня язык не поворачивается их так называть. По воспоминаниям детства, олимпийка — только советская и только синяя. Я не помню кто её носил, кажется папа, а может я сам, а может все.
«Жаворонкам» о «совах»
Жена показала прекрасный текст в журнале пользователя r2r на «@дневниках» о том «как чувствует себя „сова“ в мире, где работают с 8:30». Если ещё не читали, прочитайте. Если вы, к тому же, ещё и «жаворонок», читайте обязательно!
Я именно так себя и чувствую, когда приходится вставать рано. Я — «сова». Нет, это нельзя исправить. Девять лет школы, четыре года техникума, пять лет в университете и везде приходилось приходить рано. Как я не старался, но я спал на уроках и первых парах, ничего с этим поделать нельзя. По статистике 15% людей — яркие «жаворонки» и «совы», нас не переделать.
Добавлено 21 ноября 2009 15:32: Бирман у себя в комментариях очень правильно написал: «сова — это не тот, у кого режим дня ложиться
mod_rewrite: просмотр списка правил только один раз
У модуля mod_rewrite сервера «Апач» есть особенность, которая иногда портит много крови — после каждого переписывания URL, он просматривает список правил снова. Если ничего не предпринять, иногда происходит зацикливание, что ввергает новичков в ступор.
Мне эта особенность ни разу не пригодилась, но избавляться от неё приходится постоянно. В комментариях на «Хабре» к статье, название которой я вынес в заголовок, подсказали очень хороший способ, добавить первым правилом следующее:
# Don't loop.
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]Если перезапись URL уже происходила, то любой URL оставляем без изменений и следующего цикла обработки уже не происходит.
Функциональное тестирование и Selenium
Посмотрел «Selenium» — прекрасный, на мой взгляд, инструмент для автоматизации функционального тестирования. Из аналогов я нашёл только «Watir», но он мне показался сильно беднее (или только показался?). Платных аналогов много, в том числе от именитых IBM и HP, но хочется именно бесплатного.
Собственный опыт у меня пока небольшой (я написал несколько тестов и бегло прочитал документацию), а из прочитанного в сети я сделал вывод, что у «Селениум» есть проблемы. Вроде как он не любит фреймы (сомнительно) и стабильно работает только в Firefox (мне FF пока достаточно).
Я пока использовал только версию для Firefox (дополнение Selenium IDE). Самый простой способ изготовить тест выглядит следующим образом: открываем Selenium IDE, создаём новый тест, подготавливаем браузер (переходим на страницу, с которой тест начнётся), жмём на красную кнопку записи (справа на панели инструментов), в браузере выполняем
После того как последовательность действий в браузере была записана «Селениумом», нужно посмотреть что получилось, возможно
Вот простенький тест, который я записал, что проиллюстрировать принцип:
сохраняем тестовую строку
store THIS-IS-TEST-STRING testPhrase
открываем страницу в браузере
open /EvgenyStepanischev
жмём на ссылку, в которой содержится указанное значение и ждём, когда браузер её полностью загрузит
clickAndWait link=EvgenyStepanischev / Тестирование
жмём на ссылку, которая выбирается CSS-селектором
clickAndWait css=.edittab a.b-button-yellow
печатаем
type postText ${testPhrase}
жмём на клавишу с указанным ID
clickAndWait really_save_button1
проверяем есть ли на странице наш текст
assertTextPresent ${testPhrase}Чтобы тест выполнился, нужно указать для него базовый URL (по которому будет выполняться тест и нажать кнопку запуска теста и тест сьюта). На нашей внутренней «Вики» в «Яндексе» этот тест откроет мой кластер, найдёт там страницу «Тестирование», нажмёт на ней кнопку редактирования, напечатает в страницу
Большинство потребностей покрывается языком «Селениума»,
Есть возможность удалённого запуска тестов на нескольких браузерах и использование языков C#, Perl, Ruby, Python, PHP и Java, но я пока с этим богатством не разбирался, первые потребности вполне покрываются тем, что я уже знаю, дальнейшее — дело будущего.
Добавлено 22 ноября 2009 13:40: Андрей Ларионов подсказал ещё один бесплатный продукт — «Tellurium», но я не вижу преимуществ перед «Селениумом», зато вижу недостатки, например, усложнённый (по сравнению с «Селениумом») язык описания тестов.
KeyRus
Олег, братишка, ты помнишь программу «KeyRus»? Отличный русификатор для DOS, им вся страна пользовалась, компактный, мощный, функциональный. Наше самонадеянное желание сделать меньший по размеру? Что мы тогда знали о сжатии и работе видеоадаптера? Помнишь как удивлялись, что после беты восьмой версии мы не могли найти релиз?
Случайно зашёл на страницу «кейруса» в Википедии, оказалось, что её автор Дмитрий Гуртяк умер
Видимо, в последние годы ему было не до «кейруса», мда.
Импорт ЖЖ
Очень хочется импортировать сюда, в блог, свой старый ЖЖ. Конвертор давно готов (написал за пару дней ещё в феврале), но всё не решусь запустить —
У меня они и используются. Если я симпортирую сюда весь ЖЖ, то пользователи «Яндекс.Ленты» увидят все эти записи (сколько их там не помню, ну пусть 800) как новые, что плохо, я такого себе позволить по отношению к читателям не могу, а что делать не знаю. Можно сделать импорт, но не показать эти записи роботу «Яндекса», тогда они не будут находиться через «Яндекс.Поиск по блогам», который я использую как поиск по своему сайту.
Куда не кинь, всюду клин.
А ещё и бы и старый сайт импортировать, с 11 ноября 2000 года по 4 июля
未翻譯
Поднимался по мраморной лестнице во внутреннем дворике «Яндекса», капли дождя, накапливаясь на верхней площадке, срываются на ступеньку ниже, и ниже, и ниже. Я — исполин, идущий по долине муравьиных водопадов.
Яндекс.рф
Компания «Яндекс» зарегистрировала домен Яндекс.рф:
domain: XN--D1ACPJX3F.XN--P1AI
state: REGISTERED, NOT DELEGATED, VERIFIED
org: YANDEX, LLC.
phone: +7 495 7397000
fax-no: +7 495 7397070
e-mail: noc@yandex.net
registrar: RUCENTER-REG-RF
created: 2009.11.25
paid-till: 2010.11.25
source: TCIЕсть так же Рамблер.рф, Кремль.рф, Москва.рф, Россия.рф, Мир.рф, Труд.рф, Газета.рф и, видимо, многие другие.
Вполне себе развлечение — угадать какие имена могут быть заняты.
Web Standards Days через 2 дня
Минск
Немного не повезло на въезде в город — прилетал Медведев и прямую трассу в Минск закрыли для простых смертных, зато таксист (ехали из аэропорта) сполна отработал двойной тариф, который он с нас слупил. Заехали в гостиницу «Беларусь» — чистенькую, но совковую. Совковость чувствуется во всём, в номере холодно (+6 на улице, в номере, похоже, не топят), персонал хамит, порою действует соверешенно неадекватно.
Складывается ощущение (не знаю так ли это), что ресторан «Панорама»
Беларуский рубль — это примерно в 95 раз меньше, чем российский, что незаурядно травмирует мозг поначалу (400 тысяч за номер в отеле?! 127 тысяч за такси??!), но постепенно начинаешь незаметно убирать два нуля и испокаиваешься (сколько надо доплатить за завтрак — 32000? а! это же
Input multiple
Я
<input type="file" name="input" multiple="true" />Ещё более интересно, что в свежей бете (№4) этого браузера есть возможность (как я понял) получить доступ к выбранным файлам
Попробовал посмотреть как выгдядит прикрепление нескольких файлов со стороны PHP, оказалось всё просто — достаточно сказать PHP, что из входящих данных нужно сделать массив и всё работает (например, указать name=«input[]»): в каждом поле каждого элемента массива $_FILES содержится массив значений. Вот как это выглядит для двух файлов:
array(1) {
["input"]=>
array(5) {
["name"]=>
array(2) {
[0]=>
string(14) "2009.09.23.jpg"
[1]=>
string(14) "2009.08.25.jpg"
}
["type"]=>
array(2) {
[0]=>
string(10) "image/jpeg"
[1]=>
string(10) "image/jpeg"
}
["tmp_name"]=>
array(2) {
[0]=>
string(18) "Z:\tmp\php3740.tmp"
[1]=>
string(18) "Z:\tmp\php3741.tmp"
}
["error"]=>
array(2) {
[0]=>
int(0)
[1]=>
int(0)
}
["size"]=>
array(2) {
[0]=>
int(35005)
[1]=>
int(63030)
}
}
}Конструкция работает в Chrome с версии 3.0.191.0 и в Safari с версии 4.0.1. К сожалению, в Opera 10.20 alpha 1 поддержки нет, в IE8 — тоже.
Добавлено 29 ноября 2009 23:08: оказывается, «Опера» поддерживала с версии 3.5 загрузку сразу нескольких файлов в обычном, «однофайловом» диалоге,
Добавлено 29 ноября 2009 23:14: «Опера» 9.0 и выше поддерживает загрузку множества файлов в одном контроле, достаточно указать параметры min и max:
<form enctype="multipart/form-data" method="post">
<input type="file" min="1" max="9999" name="file" />
<input type="submit" name="submit" />
</form>Плохие новости заключаются в том, что PHP такой запрос от «Оперы» разбирать не умеет.
Добавлено через год: в «Опере» 11 атрибуты «min» и «max» удалили, но зато работает «multiple».
Input multiple-2
По мотивам предыдущего поста. Чтобы Opera 9+ (а так же 3.5—6.05), Firefox 3.6+, Chrome 3.0.191.0+ и Safari 4.0.1+ позволили выбрать несколько файлов в диалоге загрузки файлов, нужно написать вот такой код:
<form enctype="multipart/form-data" method="post">
<input type="file" min="1" max="9999" name="file[]" multiple="true" />
<input type="submit" name="submit" />
</form>Я указал «file[]» для того, чтобы PHP сразу разложил полученные файлы по массиву $_FILES. К сожалению, запрос от «Оперы» PHP понимает неверно, так как «Опера» шлёт такой запрос в формате multipart/mixed. К счастью, PHP в этом случае положит содержимое файлов одним
Я попробовал, это несложно. Для того, чтобы разобрать
if (isset($_POST['file'], $_POST['file'][0])) {
if ($idx = strpos($_POST['file'][0], "\n")) {
$bound = substr($_POST['file'][0], 2, $idx-2);
$body = "MIME-Version: 1.0\nContent-type: multipart/form-data; boundary={$bound}\n\n".
$_POST['file'][0];
unset($_POST['file'][0]);
$f = &$_FILES['file'];
$f['name'] = $f['type'] = $f['tmp_name'] = $f['error'] = $f['size'];
$msg = mailparse_msg_create();
if (mailparse_msg_parse($msg, $body)) {
$i = 0;
foreach(mailparse_msg_get_structure($msg) as $st) {
$section = mailparse_msg_get_part($msg, $st);
$data = mailparse_msg_get_part_data($section);
if ($data['content-type'] == 'multipart/form-data') {
continue;
}
ob_start();
if (mailparse_msg_extract_part($section, $body)) {
$tmp = tempnam(sys_get_temp_dir(), 'php');
file_put_contents($tmp, ob_get_clean());
$f['name'][$i] = $data['disposition-filename'];
$f['type'][$i] = $data['content-type'];
$f['tmp_name'][$i] = $tmp;
$f['error'][$i] = 0;
$f['size'][$i] = filesize($tmp);
$i++;
} else {
ob_end_clean();
}
}
}
unset($f);
mailparse_msg_free($msg);
}
}
var_dump($_FILES); // результат помещатся в $_FILES, не забудьте удалить временные файлы после обработки!У меня ожидается, что содержимое файлов будет передано как параметр «file[]» (в $_POST это будет $_POST[’file’][0]), но пример несложно переделать на любое другое имя или сделать это имя параметром.