среда, 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

четверг, 29 августа 2013 г.

Об итерировании статичных массивов в .NET, часть 2

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


В первой части я встретился с весьма интересной ситуацией. Были измерены скорости работы двух методов, в первом из которых считалась сумма элементов массива, ссылка на который хранилась в обычном поле объекта, а во втором — массива, ссылка на который хранилась в статичном поле. Результаты меня удивили: массивы были одинаковые, но второй метод работал ощутимо дольше. Сперва я подумал, что дело в организации скорости доступа к статичным полям, но более детальный анализ ситуации и разговоры с коллегами помогли мне понять, что истинная причина такого поведения намного интересней: для массивов, длина которых кратна 4, JIT использует различные оптимизации в случае обычных и статичных массивов. Давайте разберёмся с ситуацией более детально.

среда, 28 августа 2013 г.

Совершенный код и реальные проекты

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dev/perfect-code-and-real-projects/.


У меня есть проблема — я перфекционист. Я люблю совершенный код. Ведь это не только правильный подход к написанию программ, но и настоящее искусство. От чтения хорошего листинга я получаю не меньше удовольствия, чем от чтения хорошей книги. Проектировать архитектуру большого проекта ничуть не легче, чем проектировать архитектуру большого здания, а в случае хорошей работы — результат не менее прекрасен. Порой меня завораживает то, как изящно переплелись паттерны проектирования в создании совершенной программной системы. Меня восхищает внимание к деталям, когда абсолютно каждый метод настолько прост и понятен, что претендует на место классического примера совершенного кода.

Но, увы, всё это великолепие разбивается о суровую действительность и реальные проекты. Если мы говорим о продакшн-проекте, то пользователей не волнует, насколько красив ваш код и насколько хороша архитектура, их волнует, чтобы проект хорошо работал. Но я всё равно считаю, что в любом случае нужно стремиться писать правильно, просто при этом фанатизма быть не должно. После чтения различных холиваров на тему правильных подходов к написанию кода мне в глаза бросилась одна тенденция: каждый пытается применить означенные подходы не в целом к программированию, а только к своему опыту разработки, к своим проектам. Многие не осознают, что хорошие практики — это не абсолютные правила, которые должны строго соблюдаться в 100% сценариев, это лишь советы о том, как следовало бы поступать в большинстве ситуаций. На каждую хорошую практику всегда можно придумать несколько дюжин примеров, в которых она работать не будет. Но это вовсе не означает, что хорошая практика не такая уж и хорошая, просто её применили не к месту.

Комментировать или не комментировать?

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


По-настоящему хороший комментарий — тот,
без которого вам удалось обойтись.
© Дядюшка Боб


В последнее время меня стали очень утомлять оживлённые дебаты о том, нужно ли комментировать код. Как правило, по одну сторону баррикад — самоуверенные джуниоры, имеющие непререкаемую позицию вида «А как же его не комментировать, ведь без комментариев непонятно будет!». По другую — умудрённые опытом сеньоры. Они понимают, что если возможно обойтись без комментариев, то «Лучше бы, чёрт возьми, так и сделать!». Наверное, у многих жажда комментировать идёт со студенческой скамьи, когда товарищи преподаватели заставляли комментировать каждую строчку, «чтобы студент лучше разобрался». В реальном проекте не должно быть кучи комментариев, которые только и делают, что засоряют код. Впрочем, я не агитирую вообще не писать комментарии, но если вам удалось написать такой код, который не требует пояснений, то расценивайте это, как свою маленькую победу. Сразу хотелось бы сослаться на нескольких очень умных книжек, на основе которых формировалась моя позиция. Я люблю и уважаю авторов этих работ, полностью разделяя их мнение.

понедельник, 26 августа 2013 г.

Недокументированные ключевые слова C# или превращаем объект в тыкву

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


Стандартный компилятор C# поддерживает 4 недокументированных ключевых слова: __makeref, __reftype, __refvalue, __arglist. Эти слова даже успешно распознаются в Visual Studio (хотя, ReSharper на них ругается). Они не даром исключены из стандарта — их использование может повлечь серьёзные проблемы с безопасностью. Поэтому не нужно их использовать везде подряд, но в отдельных исключительных случаях они могут пригодится. В этом посте я обсужу предназначение недокументированных команд, рассмотрю вопросы их производительности и научусь превращать объект в тыкву.

воскресенье, 18 августа 2013 г.

Об итерировании статичных массивов в .NET, часть 1

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


Содержание поста было обновлено: результаты были уточнены, появилась вторая часть с подробным объяснением сложившейся ситуации.

Управляемый подход платформы .NET делает жизнь разработчиков достаточно простой, беря на себя многие рутинные операции. Большую часть времени программист может вообще не вспоминать о технической реализации платформы, сосредоточившись исключительно на логике своего приложения. Но иногда попадаются задачи, критичные по производительности. Существует множество различных подходов к оптимизации кода в таких ситуациях вплоть до переписывания наиболее важных частей кода через неуправляемый код. Однако, зачастую для увеличения скорости приложения достаточно понимать, сколько времени тратится на ту или иную операцию. Знание подобных вещей позволит оптимизировать некоторые методы с помощью достаточно простых модификаций исходного кода.

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

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

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


Платформа .NET поддерживает два способа задания многомерных массивов: прямоугольные (rectangular) и изломанные (jagged). Второй способ по сути представляет собой массив массивов. Это обстоятельство создаёт у многих программистов иллюзию того, что jagged-массивы должны работать медленнее, т.к. обращение к их элементам реализуется через многократные переходы по ссылкам в управляемой куче. Но на самом деле jagged-массивы могут работают быстрее (если речь идёт непосредственно о работе с массивами, а не о их инициализации), ведь они представляют собой комбинацию одномерных (single) массивов, работа с которыми в CLR весьма оптимизирована (за счёт IL-команд newarr, ldelem, ldelema, ldlen, stelem). Другим подходом к представлению многомерных данных является использование одномерного массива с ручным преобразованием координат (в массиве размерности N*M для обращения к элементу [i,j] будем писать [i*M+j]). Если производительности не хватает, то можно использовать неуправляемый код, но этот случай мы сейчас рассматривать не будем, остановимся на трёх вышеозначенных способах. Для замеров времени используется BenchmarkDotNet. Рассмотрим C# код, который замеряет время работы каждого варианта (полный вариант кода: MultidimensionalArrayProgram.cs, тестировать следует в Release mode without debugging). Данные результаты получены в сборке под x64 для процессора Intel Core i7-3632QM CPU 2.20GHz и параметров N=M=100, IterationCount=100000. Исследование вопроса о влиянии используемой архитектуры и параметров запуска на результат бенчмарка можно найти во второй части статьи.

вторник, 13 августа 2013 г.

четверг, 8 августа 2013 г.

Неожиданное место для сборки мусора в .NET

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


Платформа .NET обеспечивает нас высокоинтеллектуальным сборщиком мусора, который избавляет от рутины ручного управления памятью. И в 95% случаев можно действительно забыть про память и связанные с ней нюансы. Но вот оставшиеся 5% обладают своей спецификой, связанной с неуправляемыми ресурсами, слишком большими объектами и т.д. И тут лучше бы хорошо разбираться в том, как производится сборка мусора. В противном случае вас могут ждать очень неприятные сюрпризы.

Как вы думаете, может ли GC собрать объект до того, как выполнится последний из его методов? Оказывается, может. Правда, для этого необходимо запустить приложение в Release mode и отдельно от студии (without debugging). В этом случае JIT-компилятор сделает определённые оптимизации, в результате которых такая ситуация возможна. Разумеется, делает он это только тогда, когда в оставшемся теле метода нет ссылок на сам объект или его поля. Казалось бы, достаточно невинная оптимизация. Но она может привести к проблемам, если мы имеем дело с неуправляемыми ресурсами: сборка объекта может произойти до того, как закончится операция над неуправляемым объектом, что вполне вероятно повлечёт падение приложения.

среда, 7 августа 2013 г.

Неочевидности в использовании C#-замыканий

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


Язык C# даёт нам возможность пользоваться замыканиями — мощным механизмом, который позволяет анонимным методам и лямбдам захватывать свободные переменные в своём лексическом контексте. И в .NET-мире многие программисты очень любят использовать замыкания, но немногие понимают, как они действительно работают. Начнём с простого примера:

public void Run()
{
  int e = 1;
  Foo(x => x + e);
}

Ничего сложного тут не происходит: мы просто «захватили» локальную переменную e в лямбду, которая передаётся в некоторый метод Foo. Посмотрим, во что компилятор развернёт такую конструкцию*:

public void Run()
{
  DisplayClass c = new DisplayClass();
  c.e = 1;  
  Foo(c.Action);
}

private sealed class DisplayClass
{
  public int e;

  public int Action(int x)
  {
    return x + e;
  }
}

вторник, 6 августа 2013 г.

Проблема с FPU при вызове .NET-логики из Delphi

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


Ситуация: мы пишем основную логику приложения на C#, но есть необходимость использовать её из Delphi. Для этих целей пользуемся COM-обёрткой, которая успешно справляется с поставленной задачей. Целевая функция перед возвращением результата показывает диалоговое WPF-окно, с которым можно сделать что-нибудь полезное. Проверяем на простом примере — всё отлично работает.

Проблема: в некоторых Delphi приложений окно выбрасывает исключение. Но исключение странное: при формировании WPF-окна падает, скажем, выставление ширины некоторого элемента. Но это только в некоторых приложениях. А в остальных — тот же самый код на тех же самых данных отлично работает.

В чём же дело?

среда, 17 июля 2013 г.

FastColoredTextBox — божественный RichTextBox для .NET

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


Появилась у меня недавно задачка сделать в WPF-приложении красивый редактор форматированного текста с определённой логикой обработки. И решил я использовать для этой задачи стандартный RichTextBox. Увы, практика показала, что этот контрол ужасно медленный. Можно было, конечно, написать свою реализацию, но это занятие долгое, а функционал нужно было прикрутить побыстрее. Первая мысль была захостить стандартный RichTextBox из WinForms. Он работает достаточно быстро, но его функционала мне не хватило. И тогда я пустился в поиск сторонних контролов. Каким же счастливым я стал, когда наткнулся на FastColoredTextBox! Изучение контрола лучше всего начать со статьи на CodeProject. Увы, NuGet-пакет автор по каким-то причинам делать не хочет, но зато есть исходники на GitHub. Итак, небольшой обзор.

воскресенье, 14 июля 2013 г.

OverAPI.com — Collecting All Cheat Sheets

OverAPI.com — это замечательный ресурс, на котором собраны шпаргалки по самым разным языкам и технологиям. Я очень люблю разные Cheat Sheets: когда пишешь на большом количестве разных языков, то начинаешь забывать где и как называются нужные тебе функции. Конечно, есть google и документация, но с их помощью далеко не всегда можно найти нужную информацию. Намного приятнее, когда все наиболее распространённые шутки собраны в одном месте (особенно, если есть описание и ссылки на мануалы). В этом отношении OverAPI.com — отличный сайт, свёрстан на хорошем уровне, пользоваться удобно. Единственное, для многих технологий шпаргалки пока весьма скудные, но я надеюсь на развитие ресурса. К тому же, можно помочь проекту своими материалами через GitHub.

вторник, 9 июля 2013 г.

Баг поля ввода пароля Skype

Тестирование ПО — очень сложное занятие. А тестирование пользовательского интерфейса — одно из самых сложных в царстве тестирований. Всё дело в том, что количество пользовательских сценариев невообразимо большое, очень сложно предугадать всё то, что пользователь будет делать с вашей программкой. Иной раз в приложение закрадываются хитрые ошибки, которые долгое время никто не правит, т.к. никому не приходит в голову сделать именно эту последовательность действий.

Рассмотрим стартовую форму Skype, тот её участок, в котором предлагается ввести логин и пароль:

Сможете ли вы тут найти хоть сколько-нибудь неверное поведение?

вторник, 25 июня 2013 г.

Вопросы на знание строк в .NET

Меня всегда веселят .NET-разработчики, которые говорят, что они всё знают про строки. Не, ну есть и такие, которые действительно всё знают. Но обычно я с лёгкостью накидываю несколько вопросов, после которых мой собеседник теряет значительную долю уверенности в собственных знаниях. Предлагаю вам список из нескольких достаточно простых вопросов на знание типа System.String.

среда, 19 июня 2013 г.

Материалы по Git

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


Основные: Интерактивные обучалки:

Просмотр истории коммитов в Git

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


Изучение истории коммитов — важная составляющая работы с репозиторием. Увы, ввиду ветвления с этой историей не всегда просто разобраться. Обычно я для этой цели пользуюсь различными визуальными оболочками, но не всегда есть такая возможность. Временами приходится пользоваться средствами консоли, а именно командой git log. Основы работы с этой командой можно почитать в чудесной книге ProGit. git log имеет множество различных полезных параметров. Рассмотрим несколько примеров их использования.

Древовидный вид

git log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
Выводим полный граф коммитов c сокращёнными хешами, ссылками на коммиты и относительной датой. Используемый формат: синий сокращённый хеш коммита, зелёная дата, белые сообщение и автор, жёлтые ссылки на коммит.

четверг, 6 июня 2013 г.

Использование изменяемых структур в свойствах классов

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


Названия всех классов вымышленные,
все совпадения абсолютно случайны.

Занимался я как-то раз улучшением кода проекта. И наткнулся вот на такие строчки:

public class Image
{
  public Rectangle Bounds;
}

«Ай-яй-яй! Публичное поле в классе, как же нехорошо-то! Нужно срочно превратить его в свойство!» — подумал я. И превратил:

public class Image
{
  public Rectangle Bounds { get; set; }
}

Сделал я такое невинное изменение и сразу пошёл дальше рефакторить — ведь ещё такое количество кода нуждалось в улучшении! Ну а в конце решил я запустить на всякий случай Unit-тесты. Какого же было моё удивление, когда половина тестов упала. «Да как же так! Ведь я особо-то ничего и не менял!» Ну, поехали разбираться.

понедельник, 3 июня 2013 г.

Заворачиваем C#-класс в COM

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


Пусть у нас имеется C#-класс, который делает что-нибудь полезное, например:

public class Calculator
{
    public int Sum(int a, int b)
    {
        return a + b;
    }
}

Давайте создадим для этого класса COM-интерфейс, чтобы его функциональность можно было использовать в других местах. В конце посмотрим на использование этого класса в среде Delphi.

Занимательное о шрифтах в .NET

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


Сегодня мы поговорим о замечательном классе Font. Иногда при работе с шрифтами возникают некоторые вопросы, которые не настолько очевидны, как хотелось бы. Рассмотрим несколько из них.


Q: Как опознать моноширинный шрифт?

A: Это не такой простой вопрос. Если немного погуглить, то можно найти следующий совет: описываем у себя в проекте класс LOGFONT и используем метод ToLogFont для конвертации шрифта в соответствующий объект. После этого (согласно легенде) в поле lfPitchAndFamily первый бит должен определять моноширинность шрифта. Так вот, это враньё, в современном мире поле всегда будет равно нулю. Когда-то где-то этот способ работал, но сейчас не работает. В реальности приходится использовать не очень красивое, но весьма эффективное решение типа такого:

// graphics — заранее созданный экземпляр класса Graphics
public static bool IsMonospace(Font font)
{
    return Math.Abs(graphics.MeasureString("iii", font).Width - 
                    graphics.MeasureString("WWW", font).Width) < 1e-3;
}

Вызов R-скрипта с аргументами из консоли

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


Для выполнения R-скрипта из консоли нам понадобится помощь утилит Rscript.exe и Rterm.exe. Разница между ними состоит в том, что Rscript.exe в результате выполнения выдаст нам только результат работы R-скрипта, а Rterm.exe выдаст полный лог R-сессии (включая стартовое приглашение к работе и все исполняемые команды). Если быть до конца честными, то Rscript.exe по сути вызывает Rterm.exe с специальными аргументами (об этом немного ниже). Рассмотрим пример запуска скрипта с аргументами командной строки:

Rterm.exe --no-restore --no-save --args 100 image <script.R >output.txt
Rscript.exe script.R 100 image >output.txt

Разберём эти команды чуть подробней.

LaTeXTemplates.com — подборка LaTeX-шаблонов

Обнаружил в интернете свежую бесплатную подборку LaTeX-шаблонов: www.latextemplates.com. По шаблонам организована удобная навигация, для каждого доступен предварительный просмотр с кратким описанием. На текущий момент имеются следующие категории: академические журналы, статьи, задания, книги, календари, постеры для конференций, сопроводительные письма, резюме, эссэ, деловые письма, лабораторные книги, лабораторные отчёты, разное, презентации, диссертации и титульные листы.

Увы, это на все случаи жизни шаблонов не сделаешь. Для написания русской кандидатской диссертации пришлось делать собственный: Russian-Phd-LaTeX-Dissertation-Template.

Ручное размещение полей структуры в C#

Начнём с задачки. Имеется структура:

struct MyStruct
{
    public Int16 Value;
}

Требуется научится получать младший байт поля Value. Но сделать это нужно так, чтобы обеспечить максимально возможную производительность.

LaTeX-ссылки

Основные

Литература

Шаблон диссертации в LaTeX

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


Написать диссертацию — дело нелёгкое. А оформить её ещё сложнее. Благо, есть LaTeX, который может нам в этом помочь. Но для начала было бы здорово обзавестись шаблоном, на основе которого можно было бы сразу приступить к написанию научной работы. Я такого шаблона не нашёл, поэтому решил сделать его сам, возможно кому-то пригодится: https://github.com/AndreyAkinshin/Russian-Phd-LaTeX-Dissertation-Template. В шаблоне используется моя любимая кодировка UTF-8. Список литературы генерируется BibTeX-ом, а в отдельной папке аккуратно сложены всевозможные библиографические UTF-8-стили. Используются красивые PSCyr-шрифты, все наиболее часто используемые пакеты подключены. Помимо шаблона диссертации, проект также включает шаблоны автореферата, презентации и черновика для промежуточных наработок.

Рекомендации по созданию постера

В интернете есть много разной информации про то, как нужно делать хорошие презентации. А вот про создание постеров почти ничего нет. Мне недавно довелось присутствовать на одной постер-сессии. Некоторые постеры мне очень понравились, а над некоторыми ещё нужно работать и работать. И я решил сформулировать некоторые небольшие рекомендации для тех, кто собирается сделать хороший постер.

Операторы +=, -= в R

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


Продолжаем писать полезные операторы для языка R. В большинстве современных языков есть операторы +=, -= и т.п., они делают синтаксис более лаконичным. А давайте и в R определим подобные операторы, чтобы вместо
x <- x + 3
y <- y - 2
мы могли бы писать:
x %+=% 3
y %-=% 2

Множественное присваивание в R

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


R — мощный и лаконичный язык. С помощью коротких инструкций можно сделать очень многое. Но давайте сделаем R ещё лаконичнее.

Чего мне всегда не хватало в R — так это множественного присваивания. Из-за отсутствия этой возможности приходится иногда писать не совсем красивый код для получения результата функции, который должен распределиться по нескольким переменным:

x <- solve(matrix(c(2, 0, 0, 3), ncol=2), c(1, 1))
x1 <- x[1]
x2 <- x[2]
А вот было бы здорово если бы такие вещи можно было записывать в одну строчку, например так:
с(x1, x2) %=% solve(matrix(c(2, 0, 0, 3), ncol=2), c(1, 1))
Нет ничего проще!

R Syntax Highlighter — раскрашиваем R-код на вашем сайте

Появился новый прекрасный highlighter для языка R: http://highlight.r-enthusiasts.com/. Подключаем в head-секцию вашей веб-страницы нужный js-файл, оборачиваем R код в <pre></pre>, а затем из js говорим на него: $("#code").r_syntax_highlight();. И наш код раскрашивается прекрасным образом. И не просто раскрашивается: у всех команд появляется ToolTip с документацией, а сами команды — ссылки на удобную online-документацию. Всё сделано, прям как людей, это радует.

Работаем с rgl на Shiny


Shiny — это замечательный пакет, который позволяет развёртывать веб-страницы на основе R-скриптов. rgl — это замечательный пакет, который позволяет строить в R красивые интерактивные трёхмерные графики. А ещё более замечательным является тот факт, что эти пакеты можно совместить, получив в результате интерактивный трёхмерный график для вашего сайта. О том, как это сделать, рассказывает и показывает Jeff Allen в своём посте. Вы можете сразу посмотреть результат на двух примерах: arbitrary 3d points и color plots. Исходный код доступен на GitHub.

Progress bar в R

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


Давайте поговорим о долгих расчётах, ведь они не так редко встречаются в мире вычислений. Когда вы запускаете скрипт, который будет заведомо долго работать, то приятно смотреть на состояние прогресса. Эта информация поможет прикинуть время до конца вычислений («осталось ещё 30%, я успею выпить чашку кофе») или просигнализировать о бесконечном цикле («1438% выполнено, что-то пошло не так...»). Давайте научим наш скрипт сообщать пользователю о проценте выполненных работ.

stringr — работаем со строками

Пакет stringr предоставляет нам ряд замечательных функций по работе со строками. Ниже представлен краткий обзор предлагаемого функционала.

Rprofile — кастомизируем рабочее окружение

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


Давайте поговорим о задании окружения в R. Для этой цели имеется два волшебных файла:
  • Rprofile.site — глобальный файл настроек для всех сессий. Путь в Windows: c:\Program Files\R\R-x.y.z\etc\Rprofile.site, путь в Linux: /etc/R/Rprofile.site.
  • .Rprofile — локальный файл настроек для текущей сессии. Лежит в домашней директории пользователя.
Эти файлы строятся единообразно, в них можно задать глобальные настройки окружения и объявить две полезных функции:
  • .First <- function() { ... } — функция, которая запускается в начале R-сессии
  • .Last <- function() { ... } — функция, которая запускается в конце R-сессии
На Stackoverflow можно посмотреть какие .Rprofile-файлы используют люди. Взглянем, что же можно полезного сделать в таком файле на небольших примерах.

Конкатенация строк в R

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


Давайте поговорим о конкатенации строк. Новички в R пытаются пробовать стандартную конструкцию
"a" + "b"
Но их постигает неудача — R так не работает. Оператор плюс — это арифметическая операция, её нельзя применять к строкам. В R полагается использовать функцию paste:
paste (..., sep = " ", collapse = NULL)
paste0(..., collapse = NULL)

colorfulVennPlot — рисуем цветные диаграммы Венна

Диаграммы Вена — это эффективный способ графически изображать отношения между множествами. В R есть замечательный пакет VennDiagram, который успешно решает эту задачу. Но получающиеся диаграммы получаются чёрно-белыми. Сделать картинки немного интереснее поможет пакет colorfulVennPlot. Он позволяет создавать цветные диаграммы для трёх множеств следующего вида:
Давайте разберёмся с тем, как он работает.

Рисуем комиксы в стиле xkcd

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


Многие слышали о таком замечательном комиксе, как xkcd. Это веб-комикс от Рэндела Манро о романтике, сарказме, математике и языке. Для некоторых комиксов есть переводы на русский. Для поиска и просмотра ваших любимых комиксов в R есть отдельный пакет: RXKCD. Давайте установим этот пакет и подключим его:
install.packages("RXKCD")
library("RXKCD")
Давайте поищем какой-нибудь комикс, а затем нарисуем его. Функция searchXKCD выдаст нам список всех комиксов, в описании которых встречается заданная фраза. А getXKCD выдаст нам полную информацию о комиксе по заданному номеру (включая рисование картинки).
searchXKCD("someone is wrong")
getXKCD(386)

А теперь помимо стандартных комиксов научимся рисовать свои!

Cairo — делаем графики гладкими

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


R обладает богатейшим функционалом по формированию различных графиков. К сожалению, иногда графики получается не настолько красивыми, как бы нам хотелось. Давайте нарисуем график синуса:
x <- seq(0, 10, by = 0.1)
y <- sin(x)
plot(x, y, type="l")
Если вы хорошо вглядитесь в это изображение, то увидите, что функция получилась не совсем гладкой. Дело в том, что стандартное графическое устройство не поддерживает anti-aliasing. Но не стоит грустить! Нам поможет Cairo!

R-ссылки

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


Английские полезные R-ресурсы:
  • R-project — официальный сайт
  • CRAN — официальный репозиторий пакетов
  • Bioconductor — ещё один репозиторий пакетов
  • R graph gallery — графическая галерея R
  • Inside-R — замечательно R-сообщество
  • Full manual — полные оригинальные спецификации
  • R Cookbook — разные полезные R-сниппеты для решения типовых задач
  • Quick-R — краткий обзор языка
  • Try R — online-обучалка основам языка
  • R Wiki — небольшая вики про язык R
  • R Seek — поиск информации про R
  • R Journal — журнал про R
  • Google's R Style Guide — стандарты оформления R-кода от Google
  • R by example — подборка примеров использования R
  • R FAQ — официальный FAQ
  • Functional programming — учимся функциональному программированию на R
  • crantastic — ещё одно R-сообщество
  • omegahat — ещё один R-репозиторий
  • ProgrammingR.com — и ещё один полезный сайт
  • fractalswithr — фракталы на R

Инструментарий для R

Ниже представлены разные полезные штуки, призванные сделать работу с R более приятной.
  • RStudio — прекрасная IDE для работы в R. Тут можно на русском подробно почитать про работу с этим замечательным программным продуктом.
  • Pretty R — online-сервис, который умеет красиво раскрашивать R-код.
  • Sweave, knitr — замечательные пакеты, которые позволяют встраивать R-скрипты в LaTeX-документ
  • Shiny — пакет, позволяющий развёртывать интерактивные web-приложения на основе R-скрипта (с графиками, элементами управления и т.п.)
  • StatET — плагин для Eclipse для написания на языке R
  • RPy — используем R из Python-а
  • R markdown — разметка простых документов на основе R

Функции в R

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


В R очень много разных полезных функций. И многие большие вещи можно сделать весьма быстро, написав очень мало кода. На официальном сайте есть замечательная шпаргалка на английском языке: R reference card. В сети есть несколько вольных урезанных переводов, но они не очень удобные. Ниже вашему вниманию представляется русифицированная модифицированная версия обзора основных функций R. Команды снабжены ссылками на online-мануал.