суббота, 8 февраля 2014 г.

Настраиваем конфигурации сборок в .NET

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/msbuild-configurations/.


При создании нового проекта в Visual Studio по умолчанию вы получаете две конфигурации сборки: Debug и Release. И для большинства мелких проектов этого вполне достаточно. Но с ростом проекта может возникнуть потребность добавить дополнительные конфигурации. И хорошо, если нужно добавить одну-две новые конфигурации, а если их добрый десяток? А если при этом в солюшене находится штук 20 проектов, для каждого из которых эти конфигурации нужно настроить? В данном случае управлять параметрами сборки и модифицировать их становится достаточно сложно.

В этом посте будет рассмотрен способ, с помощью которого вы сможете немного упростить себе жизнь, существенно сократив описание конфигураций сборок.

воскресенье, 19 января 2014 г.

Изменения в правилах защиты диссертаций от 1 января 2014

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/education/government-decree-842/.


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

Было: Постановление Правительства РФ от 30 января 2002 г. № 74 «Об утверждении Единого реестра ученых степеней и ученых званий и Положения о порядке присуждения ученых степеней»

Стало: Постановление Правительства РФ от 24 сентября 2013 г. № 842 «О порядке присуждения ученых степеней»

Новый документ достаточно большой (35 страниц, 86 пунктов), поэтому я решил сделать обзор наиболее важных изменений с ссылками на пункты постановлений.

вторник, 14 января 2014 г.

minted: Оформляем исходный код в LaTeX

Помнится, ещё на студенческой скамье я встречал задачу оформления исходного кода в LaTeX. В ту пору я использовал пакет listings. И я страдал. О, как же я страдал! Русские буквы не хотели дружить с UTF-8, а глаза мои текли кровавыми слезами при взгляде на итоговое форматирование. И вот, вновь я встретился с этой тяжёлой задачей. В поисках решения я наткнулся на замечательный пост в записках дебианщика Как оформить исходный код программ в LaTeX без адских страданий. Название подсказывало мне, что развлечение это не простое. Я аккуратно перепробовал все рецепты из статьи, но ни один меня не устроил. И в самом конце поста я обнаружил ссылку на замечательный пакет minted, который должен был положить конец моим страданиям.

среда, 20 ноября 2013 г.

Cache-Conscious Binary Search

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/cache-conscious-binary-search/.


Рассмотрим простую задачу: есть некоторый достаточно большой неизменный набор чисел, к нему осуществляется множество запросов на наличие некоторого числа в этом наборе, необходимо максимально быстро эти запросы обрабатывать. Одно из классических решений заключается в формировании отсортированного массива и обработке запросов через бинарный поиск. Но можно ли добиться более высокой производительности, чем в классической реализации? В этой статье мне хотелось бы рассказать про Cache-Conscious Binary Search. В данном алгоритме предлагается переупорядочить элементы массива таким образом, чтобы использование кэша процессора происходило максимально эффективно.

воскресенье, 10 ноября 2013 г.

Переписываем список коммитеров в Git

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/git/rewrite-commiter-list/.


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

$ git log --pretty=format:"%an <%aE>" | sort -u

Допустим, мы получили следующий список:

Ivan <ivan@gmail.com>
Ivan <ivan.ivanov@gmail.com>
Ivan <ivan-ivan@gmail.com>
Ivan Ivanov <ivan.ivanov@gmail.com>
Vanya Ivanov <ivan.ivanov@gmail.com>
Vanya <ivan.ivanov@gmail.com>

Наблюдаем следующую проблему: некий Иван Иванов делал коммиты, указывая каждый раз разную информацию об имени пользователя и почтовом адресе. Для начала нужно дать по рукам Ивану и сказать, чтобы больше так не делал. Лучше всего использовать для всех коммитов одинаковую учётную информацию (например, Ivan Ivanov <ivan.ivanov@gmail.com>). Проблема может встать особенно остро, если в проекте используются дополнительные сервисы, которые работают с репозиторием (code review system, build server и т.п.). Ну, а пока Иван размышляет над своим поведением, мы займёмся переписыванием истории.

воскресенье, 3 ноября 2013 г.

Jon Skeet's Quiz

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/jon-skeet-quiz/.


Однажды Джона Скита попросили сформулировать три интересных вопроса на знание C#. Он спросил следующее (оригинал вопросника, перевод статьи):

Q1. Вызов какого конструктора можно использовать, чтобы следующий код вывел True (хотя бы в реализации Microsoft.NET)?

object x = new /* fill in code here */;
object y = new /* fill in code here */;
Console.WriteLine(x == y);

Учтите, что это просто вызов конструктора, вы не можете поменять тип переменных.

Q2. Как сделать так, чтобы следующий код вызывал три различных перегрузки метода?

void Foo()
{
    EvilMethod<string>();
    EvilMethod<int>();
    EvilMethod<int?>();
}

Q3. Как заставить следующий код выбросить исключение во второй строчке с помощью локальной переменной (без хитрого изменения её значения)?

string text = x.ToString(); // No exception
Type type = x.GetType(); // Bang!

Вопросы показались мне интересными, поэтому я решил обсудить их решения.

пятница, 11 октября 2013 г.

Внутреннее устройство массивов в .NET

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/arrays-internal-structure/.


Иногда бывает полезно понимать, как выглядит внутреннее представление объектов, с которыми мы работаем. В этой статье я хотел бы поговорить о массивах: как именно они хранятся в памяти, какие IL-команды используются для работы с ними, как выглядит ассемблерный код при обращении к их элементам. Я рассмотрю три вида массивов: single (T[]), rectangular (T[,]), jagged (T[][]). Также будет затронута тема массивов с ненулевой нижней границей (T[*]) и нюансов работы с ними.

среда, 18 сентября 2013 г.

Учимся округлять в C#

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/cheatsheet-rounding/.


А знаете ли вы, что Math.Round(1.5) == Math.Round(2.5) == 2? Можете ли сходу сказать, сколько будет -7%3 и 7%-3? Помните ли, чем отличаются Math.Round, Math.Floor, Math.Ceiling, Math.Truncate? А как происходит округление при использовании string.Format? Давайте немного погрузимся в мир округлений и разберёмся с нюансами, которые не для всех могут быть очевидными.

суббота, 14 сентября 2013 г.

Вся правда о TypeHandle в .NET

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/typehandle/.


В разных умных книжках и статьях про .NET я часто наталкивался на упоминания про TypeHandle. Чаще всего пишут, что у каждого .NET-объекта в заголовке находится некоторый TypeHandle, который представляет собой ссылку на тип. Ещё пишут, что TypeHandle — это всегда указатель на таблицу методов типа. А в некоторых местах мне доводилось встречать информацию о том, что TypeHandle указывает на некий TypeDesc. В общем, я устал от неразберихи: давайте вместе разберёмся что к чему. А для этого нам придётся немного подизассемблировать, поизучать дампы памяти и залезть в исходники CLI.

суббота, 31 августа 2013 г.

Сравнение производительности массивов в .NET, часть 2

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/arrays-access-performance/.


В первой части статьи я задался задачей сравнить производительность многомерных массивов. Рассматривались данные в виде двумерного массива N*M, тестировалась скорость доступа к элементу [i,j] при итерировании по всему массиву двумя циклами. Для сравнения было выбрано три варианта: одномерный массив single[i * N + j] и двумерные массивы jagged[i][j], rectangular[i, j]. Изначально у меня получилось, что jagged-версия работает быстрее single версии, но более детальное изучение проблемы показало, что дело может измениться в зависимости от используемых JIT-оптимизаций. Разберёмся с проблемой более подробно.

Рассмотрим методы из бенчмарка с наборами параметров «100»(N=M=100, IterationCount=100000) и «101»(N=M=101, IterationCount=100001) под x86 и x64. На моей машине (Intel Core i7-3632QM CPU 2.20GHz) получились следующие результаты:

  100-x86
Single      : 1012ms
Jagged      :  772ms
Rectangular : 1460ms

  101-x86
Single      : 1036ms
Jagged      :  785ms
Rectangular : 1485ms  

  100-x64
Single      : 544ms
Jagged      : 346ms
Rectangular : 741ms

  101-x64
Single      :  785ms
Jagged      :  793ms
Rectangular : 1050ms