Оптимизируем свой собственный Inversion of Control Framework

Я люблю изобретать велосипеды для вещей, которые я очень часто использую. Свой собственный фреймворк Inversion Of Control – это как раз тот случай. Я уже как-то показывал очень простую реализацию Inversion Of Framework, которую я использую во всяческих своих приложениях Реализуем сами простой IoC контейнер (и он уже даже вырос до более интересного проекта OutcoldSolutions.Framework).

В общем, как-то я напоролся на вот это сравнение IoC Container Benchmark - Performance comparison, в котором сравнивалась производительность различных контейнеров. И тут я задался тем же вопросом о том, насколько производительный мой фреймворк. Вот результат (я уменьшил количество итераций, так что не стоит сравнивать с оригинальной статьей):

В этом списке "Outcold" – это то, что я использую сейчас (ранняя версия на github). "IoC E" – это мой вариант из предыдущей статьи, построенный на Expressions (смотри комментарий), "IoC A" – это первоначальный вариант из предыдущей статьи, построенный на обычном Activator.CreateInstance. "LightInject" – один из самых шустрых фреймворков, "Unity" – это то, что я раньше использовал везде. Самое смешное, что после той прошлой статьи – мне как сказали, что Activator медленный, и стоит использовать Expressions – я так и сделал и стал использовать реализацию "IoC E" везде (а как оказалось - это самый тормозной IoC фрейморк, который вы только можете представить). Все дело в том, что каждый раз, когда вызывался метод CreateInstance, я каждый раз компилировал при помощи Expressions код, который должен быть создавать объекты:

То есть, первая оптимизация должна была быть очень простая. Нужно было просто переписать Expressions таким образом, чтобы можно было бы их сохранять и использовать каждый раз создавая объекты одного и того же типа. Как вы видите в примере, в конструктор я передаю константы, поэтому данные Expression не получится сохранить для повторного использования, если значения для аргументов конструктора будут другие. То есть, нужно из этого создать Expression функцию, которая могла бы принимать параметры для конструктора. В результате я переписал Expression так:

Теперь я сохраняю скомпилированный Delegate, возвращаемый последней строкой. Проблема теперь в том, что единственный способ, который я знал, как вызвать этот делегат – это через DynamicInvoke (которая достаточно медленная):

В любом случае, разница с тем, как было без хранения Expression, значительная (но как мы видим, до сих пор хуже реализации с Activator):

Я не сдался, проанализировав код еще раз, запустив наш профилировщик от Visual Studio, я нашел слабое место – это DynamicInvoke. Мне нужно было найти способ, при помощи которого я мог бы конвертировать Delegate в метод. Мне пришла идея написания такого Expression:

Здесь я на входе всегда получаю массив параметров (object[]), затем я каждый элемент массива я последовательно сопоставляю с параметрами конструктора. Результат такой:

Теперь быстрее, чем Activator, но все же чуток медленнее, чем LightInject. Предполагаю, что он шустрее в силу того, что они использовали System.Reflection.Emit. Говорю в прошедшем времени, так как вижу, что последняя версия библиотеки LightInject тоже использует Expressions.

На этом я и остановился. Не самая быстрая версия у меня, но выше середины.

gMusic – мое первое приложение в Windows 8 Store

Я очень долго выбирал какое будет мое первое приложение для Windows 8. Идеи были разные. До того как я сел писать клиент для Google Music я начинал и забрасывал около 5 разных приложений. В зависимости от приложения я так же выбирал язык: HTML вместе с JavaScript, либо C# и XAML. Во всех приложениях до gMusic я пытался использовать JavaScript, откуда-то во мне есть тайная любовь к JavaScript. Но все же после очередной попытки я понял, что разрабатывать на JavaScript для меня необоснованно дорого по времени. Пробовал я и TypeScript, с которым у меня уже есть небольшой опыт по работе, но у него нет коробочной поддержки разработки Windows 8 приложений на данный момент. Главная проблема, которую встретил: при использовании mixed кода, приходится описывать все declare файлы для managed/native библиотек, если хочется их использовать в приложении.

В итоге я сдался и решил вернуться к старому доброму C# и XAML.

Идея

Как я уже говорил, идей было предостаточно. Одна из первых идей была написание простого аналога Windows Live Writer. Для него я как раз и выбрал связку HTML + JavaScript, так как при помощи HTML5 тега ContentEditable сделать Rich Text редактор очень просто. Потратил около пары недель на написания прототипа и понял, что занимает это все необоснованно много времени, и полноценный клиент я напишу только через полгода. Более того, я не предвидел популярность для этого приложения. В результате я стал метаться от идеи к идеи, пытаясь найти что-нибудь действительно интересное для меня.

Я меломан со школы, слушал и слушаю практически все, от непонятного многим людям IDM, Noise или Breakcore до Scorpions или Король и Шут (только что вернулся с концерта Muse). Помню, что основным увлечением в школьные времена для меня было откладывание денег с обедов и мороженного на покупку кассет с каким-нибудь известным только на Украине альбомом-сборником The Prodigy. В студенческие годы я начал траться уже на CD. А сейчас трачусь на Amazon MP3, Google Music Play и Microsoft Xbox Music. Пробовал пользоваться подписками, вроде Microsoft Zune Pass, поначалу понравилось, но для меня выбор там слишком маленький. Поэтому отказался в конце прошлого года от Zune Pass в пользу локального хранилища и покупки тех альбомов, которые мне действительно интересны.

А вот 20 ноября я познакомился с сервисом Google Play Music, который предоставляет возможность для хранения 20 000 песен бесплатно в облаке. На самом деле даже больше, чем 20 000, так как песни, купленные на Google Play не идут в счет (на это, видимо, и делается расчет). В итоге я подсел на этот сервис. Начал изучать клиенты, которые были для Windows Phone и Windows 8. Все было огромным разочарованием. Хорошо, что на десктопе можно было пользоваться браузером, но из-за того, что постоянно открываешь и закрываешь вкладки браузера – легко теряешься в них и сложно искать вкладку с Google Music. В итоге я понял, что это и есть интересный проект для меня. Написать что-то, чем бы я был бы рад пользоваться сам. В стиле Джобса.

Реализация

Первым делом я честным образом отправил письмо в Google с вопросом об API, и о том, собираются ли они писать приложение под Windows 8 для этого сервиса. Получил отрицательные ответы на оба мои вопроса. Полазил по интернету, нашел несколько неофициальных попыток воссоздать API для этого сервиса, один на Python, один на .NET. Python реализация была достаточно неплоха, а вот .NET реализация была просто невообразимо ужасна, да и реализовано там было только загрузка Playlists. Так же я заметил, что в Apple Store существует неофициальный клиент для Google Music, что подтолкнуло меня на мысль, что Google по крайней мере не блокирует такие клиенты.

В результате, я вооружился Fiddler2 и начал изучать все запросы, которые осуществляет браузер к Google Music. Самая большая проблема была аутентификация, а так же удержание сессии больше суток, с этим я намучался. Более того, нормальное удержание сессии до сих пор держу в бета тестировании, так как не до конца уверен, что сделал все верно. А вот реализовать все остальное, вроде редактирование плейлистов, оказалось очень просто, так как нужно было просто воссоздать запрос, который отчетливо можно было проследить в Fiddler2.

Всю навигацию внутри приложения я сделал на контролах, не пользовался никакими Page или еще чем-нибудь, реализовал достаточно простой Navigation Service. Вообще, я заметил еще со времени Windows Phone, что, если хочется хороший performance на мобильных устройствах – нужно стараться меньше использовать Bindings и стандартные контролы для отображения списков, а просто делать специализированные Layout контролы, отнаследованные от Panel. Собственно, этим я сейчас и занимаюсь для новой версии – улучшение производительности для Surface при помощи отказа от GridView/ListView и перехода на собственные Panel (со своей собственной виртуализацией). Посмотрим на сколько получится улучшить производительность и usability. Как закончу – просвещу этому отдельный пост.

Вообще, знакомство с Windows Runtime было достаточно увлекательным для меня. Вроде все тот же .NET, а чувствуешь себя как новичок. Так, когда я реализовывал свой собственный IRandomAccessStream (чтобы улучшить буферизацию треков), я наткнулся на такое огромное количество вопросов с тем, как правильно писать или читать в/из IBuffer, как непросто было найти эти extension methods в System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions. И я потратил, наверное, около 30 минут на то, чтобы разобраться, как мне сохранить картинку по url локально на диск.

Результат

О результате пока сложно говорить, так как версия пока не очень-то функциональная. Она еще во многих вещах уступает браузеру (в некоторых выигрывает, конечно же). Но небольшие результаты уже есть. Приложение находится на 12 месте в списке бесплатных приложений категории Music & Video (USA). Его скачивают более 500 раз за день уже в течение 30 дней (более 15 000 загрузок за первый месяц). Пользователи покупают версию без рекламы, причем достаточно активно. Стандартный процент покупок на количество скаченных версий – 1-2%. Покупки осуществляются, в основном, из США, дальше идет Германия, где покупок в 10 раз меньше, остальные страны можно просто делать не target audience (это еще потому, что Google Music не открыт для всех стран). Был удивлен одной покупкой из России.

Ну а кто еще не видел приложение, его можно найти по этой ссылке http://apps.microsoft.com/windows/app/gmusic/939f0859-1413-4a52-9ab6-6e50405c8c2e.

Nokia Lumia 920 за $99 в USA

У данного поста было две главные темы «Телефон за $99 - это маркетинговый обман» и «я тащусь от своего нового телефона». Но так как по первой теме оказалось, что я хотел рассказать достаточно обширно, то вторую тему оставлю на потом.

Телефон за $99

Первая темы всплыла в связи с тем, что уже не один раз я получал сообщения в твиттере, о том как нам везет в Америке покупать телефоны за такие копейки. В России они стоят безумные деньги. Хочу развеять этот миф и рассказать про то, за что мы платим в штатах. Думаю, что многие наслышаны про понятия залоченных телефонов и про контракты с сотовыми операторами, давайте об этом поподробнее.

Залоченные телефоны

Сотовые операторы, без исключения, вешают блокировку на телефоны для того, чтобы их не было возможно использовать с другими сотовыми операторами. Одна из причин – это эксклюзивность аппаратов у сотовых операторов. Например, Nokia Lumia 920 можно купить только у ATT в течение следующих 6-ти месяцев. Блокировка доставляет немало проблем людям, которым необходимо путешествовать вне штатов, так как нет возможности использовать телефон с другими симками, которые можно купить в других странах и общаться за копейки (по сравнению с нашими тарифами). При поездке начинаешь выбирать, что лучше: найти/купить где-то телефон специально для Европы, или купить «супер классный план» для путешествия, который вам обойдется в $30 за 100Мб (сколько стоят минуты разговора, не помню).

Проблемы блокировки могут быть решены на сторонних сайтах. Так, например, для своего предыдущего телефона Samsung Focus S я нашел сайт, который по IMEI выдавал коды для разблокировки, и стоило это около 25 баксов. И, в зависимости от телефонов, сотовые операторы, обычно, выдают коды разблокировки через 6 месяцев на контракте и через год после выпуска модели телефона, в зависимости от того, что наступит раньше. На какую-то версию iPhone, вроде, вообще не выдавали коды разблокировки.

Про iPhone, кстати, интересно получается сейчас. 5-ая версия продается сейчас у Verizon и ATT. Первый оператор – это CDMA, второй GSM (разные виды радио модулей). В России CDMA не очень распространен, но знаю, что в Ярославле есть CDMA оператор. Так вот, iPhone 5, как и многие другие современные модели телефонов, поддерживает сразу оба стандарта из коробки. Соответственно, Verizon блокирует CDMA модуль на себя, а GSM модуль не заблокирован. В ATT заблокирован GSM модуль, а CDMA модуль не заблокирован. То есть, в принципе, если Verizon продает телефоны без контрактов (а он продает), то можно купить телефон, которым можно будет пользоваться в России у GSM операторов. Bing: iphone 5 verizon gsm unlocked.

Контракты

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

Первый способ отлично подходит только тем, кто совершает немного звонков и больше ничем не пользуется, вроде интернетом и смс. Минуты там стоят дороже, чем в России, смс стоят, примерно, 25 центов (за *входящие* и исходящие), мегабайты там стоят больше $1. Со смартфонами такой план – себе дороже.

Второй способ – это заключить контракт на 2 года. В течение этих двух лет тебе предоставляется разовая скидка на покупку телефона, вроде, $99 за Nokia Lumia 920, $199 за самый дешевый iPhone 5. Если захочется разорвать контракт, то нужно платить около $450. А да, еще они берут $36 за активацию каждой линии (то же самое при обновлении телефона). Поделюсь о том, за что мы тут платим. Всего два телефона, оба Windows Phone. Мы сейчас платим за Family Plan, в который включено самое минимальное количество минут. Стоит он $50 за две линии (минус ~23% скидка для сотрудником Microsoft), 550 минут включено (минуты, правда только за звонки вне данного сотового оператора, внутри бесплатно). Выговорить эти 550 минут нереально, купить меньше нет возможности. На контракте обязательно покупать Data Plan на смартфоны. Мы сейчас платим за два Unlimited Data Plan, каждый из которых стоит $45. Это специальный Data Plan, который существовал год назад. У Microsoft на него тоже скидка (только на Windows Phone аппараты), в результате он стоит нам около $24 каждый. Unlimited звучит красиво, но шарить интернет на планшет или компьютер с него нельзя, нужно покупать специальный план для этого, который стоит около $38 уже со скидкой, ну и понятное дело, что скорость режется после определенного скаченного объема (думаю, что 2Гб). Можно еще купить на каждый телефон СМС план за $10 (уже со скидкой, так он стоит $20, вроде). В эти цены не включаются еще налоги, а так же всякие сборы, за всякие вышки и т.п., в результате которых еще накапливается $10. В итоге мобильная связь тут нам стоит около $106 в месяц (если особо не пользуемся СМС, и не катаемся в Канаду). И это с хорошими скидками для сотрудников Microsoft, без скидок все это стоило бы около $150 и интернет уже был бы не Unlimited.

Если вы еще помните, то я говорил, что существует третий способ оплаты. Платить столько же, сколько на контракте, но не быть на контракте, быть свободным в переходt на другого сотового оператора в любое время. Скидку на телефон не предоставляют.

Для сравнения, в России у меня был условно Unlimited интернет (ограничение, вроде, на 1Гб, после чего скорость резалась), и я платил за связь около $25 в среднем, причем разговаривал по мобильному я много (домашним телефоном не пользовался, и пользовался намного больше, чем здесь), катался часто внутри станы, по областям. Что в штатах хорошо, тут нет мобильного роуминга внутри страны. На Гавайях у меня все тот же Unlimited интернет.

Полная цена за телефон

Еще указывали, что Nokia Lumia можно купить сейчас за $449 + tax без контракта. Но телефон все так же будет заблокирован на оператора. У ATT, как вы видели, чтобы пользоваться нормально смартфоном, то придется платить нехило. Можно жить на Wi-Fi и платить поминутно. Wi-FI тут есть во всех автобусах в нашем регионе. Можно ли так жить? Я не знаю, не пробовал. Я бы, наверное, не смог. Купить телефон, найти способ разблокировать и использовать в России? Наверное, так можно. Предполагаю, что будут трудности с warranty, если потребуется. Ну и код разблокировки будет стоить определенную сумму. В общем, тут, в штатах, такая цена не просто так. И выглядит она вкусной только для вне-штатовских покупателей. Внутри штатов мы за эту цены заплатим потом у сотовых операторов.

Вывод

Так что лучше, платить за телефон $700 и $25 за связь в месяц, или $100 за телефон и $53 в месяц? За 24 месяца как раз и получается разница в $600-700, учитывайте еще активацию за $36. И я уже молчу про то, что перейти с оператора нельзя, если окажется, что у другого сотового оператора намного интереснее тариф. И нужно решать проблемы при поездках в Европу.

Недавно я еще столкнулся с warranty у ATT. У меня телефон пару раз падал на асфальт, на нем значительные царапины, но, нужно отдать должное, никаких проблем после падений не было. А вот пару недель назад я включил «Автоматическую регулировку яркости» и заметил, что у Samsung стал подвисать тач. Хотел отдать по warranty, а мне сказали так «Вы отправляете телефон, мы сразу же высылаем новый. Если оказывается, что причина в неправильном использовании, то вы платите за новый телефон $450.» По другому нельзя, вроде отослать телефон, и только если есть проблема, то высылать новый. Отличные условия? Я, понятное дело, не согласился. Так как, в случае, если виновато в этом было падение, то платить $450 за телефон, который стоит сейчас $150 на ebay, я точно не хотел. Поэтому просто вспомнил, что включил недавно «Автоматическую регулировку яркости», отключил ее, осознал, что это и являлось проблемой и успокоился.

Надеюсь, что данный топик хотя бы немного вам открыл глаза на то, почему тут такие «дешевые» телефоны. Мне казалось, что я писал о том, что, когда мы жили в Канаде, то нам дешевле было использовать Российские сим-карты с роумингом, чем связываться с местными операторами. В общем, не все тут так гладко.

Встречайте IntelliCommand (Visual Studio 2010/2012 extension)

Как много горячих клавиш вы знаете в Visual Studio? Знаете все? Я знаю способ выучить их все. Хочу представить вам расширение для Visual Studio 2010/2012, которое я написал вместе со своими коллегами Drake Campbell и Aditya Mandaleeka. Позвольте мне просто скопировать описание расширения с Visual Studio Gallery:

IntelliCommand - это расширение для Visual Studio 2010 и 2012, которое помогает находить комбинации горячих клавиш. Данное расширение показывает окно-помощник со всеми возможными комбинациями клавиш при нажатии Control, Shift или Alt, или их комбинации (по умолчанию нужно удерживать клавишу на пару секунд). Так же данное расширение показывает список возможных комбинаций, когда вы нажимаете первую комбинацию из chord shortcut keys, например, Ctrl+K, Ctrl+C (данная комбинация закомментирует код в редакторе).

Переносим сайт в Windows Azure Web Sites

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

  • Перевести домен на зону com, да теперь мой сайт находится на http://outcoldman.com.
  • Обновить внешний вид, выкинуть все лишнее, а самое главное - это добавить поддержку мобильных устройств.
  • Перенести сайт с masterhost на orcsweb, так как второй мне предоставлялся бесплатно с более интересными условиями. Больше пропускная способность. И они всегда, чуть ли не на следующий день, обновляют .NET Framework после выхода новой версии.

Как понятно из названия топика, с последней задачей я не справился. Из-за политики orcsweb выставлять medium trust для shared сайтов, что доставляет определенные неудобства. Так, например, возникают проблемы с использованием пакета AntiXSS, а так же есть мелкие проблемы с SQL Server CE.

1  2  3  4  5  6  ...