четверг, 31 декабря 2009 г.

С Новым 2010 Годом!

using namespace std;
const char NY[] = "Поздравляю с Новым Годом!";
cout << NY << endl; 
С ув. Раптор 

среда, 25 ноября 2009 г.

C#4.0 Optional Arguments

В новом C# 4.0 появилась возможность задавать значения по умолчанию для параметров функции. Данное нововведение, очевидно, перекочевало с С++ и поможет сделать код более компактным (ранее приходилось создавать тучу перегруженных функций, что было весьма неудобно).
1
Как видно из рисунка выше объявление функции с параметрами по умолчанию ничуть не отличается от того, которое есть в С++, однако C# предлагает большую гибкость. К примеру параметры по умолчанию можно передавать в разном порядке:
2
Передача параметра имеет вид
“Имя переменной”:”Значение”
Думаю данное нововведение будет весьма полезным для разработчиков.

вторник, 24 ноября 2009 г.

C# Delegate Stub

При работе с делегатами в C# есть одно маленькое неудобство: нужно выполнять проверку на null, иначе мы получим исключение.

1

Недавно нашел в сети весьма элегантное решение данной проблемы:

2

Для того, что бы не делать проверок, достаточно написать небольшую заглушку delegate {}; при объявлении. Теперь никакие исключения не возникают)

Ссылки: http://habrahabr.ru/blogs/net/67991/

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

C++0x Повторное использование лямбда-выражений

Продолжу обзор лямбда-выражений. Еще одно важное их достоинство - это возможность повторного использования и передача как параметр функции. Для сохранения лямбда-выражений в переменную используется класс std::tr1::function.




C++0x Lambda Expressions

Одним из значительных нововведений в новом С++ являются лямбда выражения. Они перекочевали к нам от функциональных языков, сначала в С# 3.0, а теперь и в новый C++0x.
Лямбда выражения представляют собой небольшие программные конструкции, которые можно вставить прямо внутри какого либо выражения. Возможность оценить лямбда выражения дает нам новая Visual Studio 2010 и GCC.  Изначально их синтаксис может показаться довольно неудобным, но если к нему привыкнуть, они помогут вам сберечь много времени, а код сделать более лаконичным.

Приведем небольшой пример. Допустим есть вектор целых чисел и нам нужно посчитать, сколько чисел больше 5. С помощью лямбда выражений это делается весьма компактно.



Рассмотрим синтаксис лямбда выражения более подробно:


1) Список захвата или capture list
2) Список параметров
3) Изменение параметра, переданного по значению (может быть опущено)
4) Спецификация исключения (может быть опущено)
5) Возвращаемый тип
6) Тело лямбда выражения



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

Для лямбда выражения можно определить список исключений, которые она может генерировать.

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

Теперь подошли к самому интересному. Любое лямбда-выражение начинается с квадратных скобок - список захвата или capture list. Значит это следующее - выражения могут обращаться к внешним переменным, которые находятся в области видимости (как по значению так и по ссылке). Список между [] определяет к каким и как именно мы будем обращаться к внешним переменным. Таким образом предыдущий пример мы можем переписать в несколько измененном виде:



 Возможны следующие варианты:
 [] - Нет обращения к внешним переменным.
 [=] - Обращение ко всем внешним переменным по значению.
 [&] - Обращение ко всем внешним переменным по ссылке.
 [=, &x] - Обращение ко всем по значению, кроме переменной x
 [&, x] - Обращение ко всем по ссылке, кроме х.
 [x, &y, z] - Обращение только к переменным x, y, z (к y по ссылке). Доступ к другим переменным отсутствует.

Как видим списки захвата дают нам большую гибкость при работе с лямбда выражениями.

При обращении к внешним переменным нужно учесть несколько нюансов.
Допустим есть следующее лямбда выражение, в котором мы локально изменяем внешнюю переменную (обращаюсь по значению) и выводим ее на экран:




К сожалению такой код компилируется с ошибкой:
Error 1 error C3491: 'X': a by-value capture cannot be modified in a non-mutable lambda main.cpp 8 1 LambdaExpressions

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

Вся проблема в том, что оператор генерируется с модификатором const, впоследствии чего переменная Х не может быть модифицирована. Решением проблемы является добавление ключевого слова mutable.


Второй нюанс при обращении к членам класса. Приведу сразу пример:

Компиляция этого кода также приведет к ошибке:
Error 1 error C3480: 'Object::X': a lambda capture variable must be from an enclosing function scope \main.cpp 11 1 LambdaExpressions

Компилятор говорит, что захватываемая переменная должна быть в области видимости. Для обращения к членам класса нужно вместо [X] объявить [this]. Код компилируется без проблем, но при этом обращение к членам класса осуществляется только по ссылке. Любые попытки сделать обращение по значению приведут к ошибке.

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

понедельник, 9 ноября 2009 г.

Visual Studio 2010 Toolbox search

Еще одна классная фича новой IDE - возможность быстрого поиска и выбора элемента в Toolbox. Для ее использования нужно установить фокус на окне Toolbox (кликнуть мышью либо комбинацией Ctrl + Alt + X) и начать вводить текст. При этом в строке состояния вы увидите соответствующую информация о вводе:



По мере ввода, VS будет автоматически  подсвечивать (и выбирать) подходящий элемент. Для перехода к следующему элементу используется клавиша Tab, для отмены поиска - Esc.

Небольшая, но приятная функция).

воскресенье, 8 ноября 2009 г.

Data Parallelism (Task Parallel Library) в NET4.

Я уже писал ранее о некоторых нововведениях NET4 и о том, как можно легко распараллелить запросы с помощью  Parallel LINQ. В .NET4 это не единственное нововведение для задач параллельного программирования, нам предоставляется возможность с такой же легкостью распараллелить циклы for и foreach. Для этого служит новое пространство имен System.Threading.Tasks.Parallel .

Рассмотрим, в качестве примера, код умножения матрицы:


Данный код легко превращается в параллельную программу:



В целях эксперимента я решил замерить скорость выполнения умножения матрицы 1000х1000 на 1 и 2 ядрах. Результаты получились следующие:
1 поток  - 40.657
2 потока -  23.514

Как и ожидалось, прирост почти в два раза.


Ссылки и другие примеры: http://msdn.microsoft.com/en-us/library/dd537608(VS.100).aspx




Visual Studio 2010 Code Metrics

Еще одно интересное нововведение Visual Studio 2010 - это возможность оценивать сложность и переносимость кода. Данная функция будет полезной для команд разработчиков, поскольку можно увидеть текущее состояние проекта и определить потенциально проблемные участки кода.

Запустить подсчет статистики можно несколькими способами:
  • Solution Explorer - Правой кнопкой по проекту - Calculate Code Metrics
  • Меню Analyze - Calculate Code Metrics for ...
  • Меня View - Other windows - Code Metrics Results. 
Предоставляются следующие данные:
  • Maintainability Index - "ремонтопригодность" =) кода. Подсчитывается индекс от 0 до 100,  который определяет сложность сопровождения кода. Данный параметр вычисляется на основании других - Cyclomatic Complexity и Lines of Code. Чем выше число, тем лучше. В той же колонке можно увидеть цветной индикатор, который имеет след. значения: зеленый - от 20 до 100, желтый - от 10 до 19, и красный - от 0 до 9. 
  • Cyclomatic Complexity -  структурная сложность кода. Тут просто подсчитывается количество операторов if, switch, do, while, foreach, for loops в блоке кода. Чем меньше, тем лучше.
  • Depth of Inheritance -  подсчитывает глубину иерархии наследования.
  • Class Coupling -  определяет количество связей (через локальные переменные, возвращаемые значения, вызовы методов и т. п.). При подсчете пропускаются встроенные типы. Разумеется, чем меньше связей, тем лучше переносимость кода.
  • Lines of Code - количество строк кода. При подсчете пропускаются комментарии, скобки, пробелы и т.п. 


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



Также Visual Studio 2010 позволяет отображать только определенные колонки и  сделать экспорт результатов в Excel.

Code Metrics работает только в управляемом коде, а жаль :'(

Ссылки: http://msdn.microsoft.com/en-us/library/bb385910.aspx

суббота, 7 ноября 2009 г.

Linq-To-Entity Dynamic Search

Недавно столкнулся с задачей динамического поиска по таблице используя Linq-To-Entity. Поиск нужно выполнять по любому полю, опционально должны быть настройки: "Содержит", "Начинается", "Заканчивается", "Равно".  А также критериев поиска может быть любое количество.

К сожалению стандартные средства LINQ не предоставляют подобной гибкости. Одним из решений было использовать LINQ Dynamic Query API. Данная библиотека совместима с любым LINQ провайдером данных (LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer). Вместо использования операторов языка и лямбда выражений, она предоставляет строковые расширения. Например.

Подобная система сводится к простой генерации строки запроса, что не составляет особого труда.
Ссылки для скачивания http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
http://www.codeproject.com/KB/WPF/LtoE.aspx

вторник, 3 ноября 2009 г.

C# Operator ??

В C# есть замечательный оператор -??. С помощью него следующее выражение:
t = (text == null) ? "" : text;
можно записать в более изящном виде:
t = text ?? "";

понедельник, 2 ноября 2009 г.

Visual Studio F1 Help Shortcut


Наиболее раздражающая вещь в Visual Studio для меня - это случайно нажать вместо Escape клавишу F1. При этом появляется окно "Help Update In Progress", которое блокирует основное окно на несколько минут.


Погуглив несколько минут, я нашел решение - это отключить клавишу F1 как таковую.

Жить стало легче (:

суббота, 31 октября 2009 г.

Параллельный LINQ

Многоядерные и многопроцессорные системы уже ни для кого не являются новостью, так как прогресс никогда не стоит на месте. В данном посте я хочу немного рассказать про набор расширений Parallel FX, а конкретно про PLINQ - механизм выполнения LINQ запросов на многоядерных системах. Отличия  с точки зрения синтаксиса в LINQ и PLINQ минимальны, все что требуется от программиста - это обвернуть источник данных в IParallelEnumerable<T> с помощью расширения System.Linq.ParallelEnumerable.AsParallel. К примеру возьмем запрос:

var T = Dat.Where(x => x.Value == 5).Select(x => x);

для его распараллеливания следует внести следующие изменения:

 var T = Dat.AsParallel().Where(x => x.Value == 5).Select(x => x);

Или же:

var T = from A in Dat.AsParallel() where A.Value == 5 select A;

Все! При выполнении запроса PLINQ сам организует запуск его частей на доступных процессорах.
Прелесть этой системы состоит в том, что от программиста вообще не требуется  никаких знаний параллельного программирования, а затраты на ее внедрение - минимальны.

Ссылки:
http://en.wikipedia.org/wiki/Parallel_Extensions
http://msdn.microsoft.com/ru-ru/magazine/cc163329.aspx

среда, 28 октября 2009 г.

IntelliTrace & Reverse Debugging в VS2010

Совсем недавно я писал про весьма удобную фишку VS2005/VS2008 - Tracepoints. В VS2010 пошли дальше и добавили - IntelliTrace (ранее известен как Historical Debugger). IntelliTrace - это вариант отладки (к сожалению доступен только для управляемого кода), при котором, кроме стандартных опций отладчика Visual Studio, вы можете выполнить полную трассировку программы, то есть просмотреть все UI события, User gestures, обращения к файловой системе, сети, реестру, LINQ запросы и т. п., а также в каждой контрольной точке видеть значение локальных переменных, call stack и т. д.

















Два раза кликнув по нужной записи - можно перейти к соответствующему участку кода в программе.

Дальше - лучше. IntelliTrace позволяет выполнять отладку как вперед так и назад. По умолчанию эта опция выключена. Для ее включения нужно поставить переключатель "IntelliTrace events and call information".














После этого во время отладки, слева от окна редактора появляется специальная панель.


Return to Call site
Go to previous call
Step in
Go to next call
Go to live mode.



Как видим, процесс отладки в VS станет заметно удобнее для программиста.

Ссылки: http://blogs.msdn.com/habibh/archive/2009/09/21/coverage-of-the-visual-studio-2010-historical-debugger.aspx

понедельник, 26 октября 2009 г.

Unigine heaven benchmark (DX11)

Ребята из Unigine выпустили бенчмарк на DX11. В демке преимущественно демонстрируется одна из основных фич ДХ11 - аппаратная тесселяция. Вынужден признать - картинка меня впечатлила. Красиво).













 Вот список ключевых фич:
* Native support of OpenGL, DirectX 9, DirectX 10 and DirectX 11
* Comprehensive use of tessellation technology
* Advanced SSAO (screen-space ambient occlusion)
* Volumetric cumulonimbus clouds generated by a physically accurate algorithm
* Dynamic simulation of changing environment with high physical fidelity
* Interactive experience with fly/walk-through modes
* ATI Eyefinity support



 Ссылки  на источник:
http://unigine.com/press-releases/091022-heaven_benchmark/
http://binstream.livejournal.com/82398.html#cutid1

четверг, 22 октября 2009 г.

Visual Studio Tracepoints

В Visual Studio есть одна интересная функция, которую я раньше в упор не замечал.
Очень часто во время отладки или тестирования кода возникает потребность выводить на экран значения тех или иных переменных. Раньше эта проблема решалась добавлением в код соответствующих методов: printf, Log, MessageBox, Console.WriteLine и т.п. Оказывается все намного проще и удобнее. В VS, начиная с 2005, есть Tracepoints. Это своего рода аналог Breakpoint, который позволяет выводить какие либо сообщения в DebugOutput. Создается трейспоинт через меню правой кнопкой, Breakpoint -> Insert Tracepoint.


 В появившемся окне можно определить формат и переменные для вывода либо макрос, который будет запускаться. Таким образом можно просматривать нужные данные не изменяя код.

суббота, 16 мая 2009 г.

Вызов чисто виртуальной функции))

Ничто так не ограничивает полёт мысли программиста, как компилятор :)) Но как сказал один мой товарищ - если иметь фантазию - можно творить чудеса... Сегодня мне в аську колега в комманде кинул интересный код вызова чисто виртуальной фукнции:

void func(class A*);

class A
{
public:
A() {func(this);}
virtual void pure() = 0;
};

class B : public A
{
public:
virtual void pure() {}
};

void func(A* a)
{
a->pure();
}

int main()
{
B* b = new B();
}

понедельник, 6 апреля 2009 г.

Думал, что мир перевернулся...

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

class A {
public:
int a;
bool b;
float c;
void debug() { printf("%i %s %f\r\n", a, b ? "true" : "false", c); }
};

int main() {
A * f; // <-- ??? f->a = 4;
f->b = true;
f->c = 4.5f;
f->debug();
return 0;
}

Дальше в лес, больше дров, мой товарищ решил совсем извратиться :))

float* f;
int i;
for (i = 0; i < 10000000; i++) {
*f = 6.0f;
printf("%f\n", *f);
}
Так работает, но после определенного числа итераций валится.

А след. кусок валится сразу (если int i обьявить в конструкции for).
float* f;
for (int i = 0; i < 10000000; i++) {
*f = 6.0f;
printf("%f\n", *f);
}

Обьяснение приблизительно следующее: в релиз варианте поинтер забивается дефолтным мусором (принцип его формирования нам остался неизвестным), но если из этого мусора сделать поинтер, то он будет указывать на доступную область памяти, в эту память можно писать. Так как нам все же доступно не все адресное пространство - то на определенном числе итерации оно валится..

четверг, 5 марта 2009 г.

Кхм... Раз два раз два... Проверка микрофона.. Я в эфире?))

Hello world.
Вот и у меня любопытство взяло верх, решил поближе познакомиться с ЖЖ )) Посмотрим, что из этого выйдет ;)