вторник, 19 мая 2009 г.

Wolfram|Alpha

На этих выходных состоялся пуск занимательного проекта Wolfram|Alpha.

Я всегда смотрел на знания как в основном на динамическую сущность. Можно знать основной закон (который не меняется), но, в последствие, используя его можно рассчитать огромное количество информации. К примеру, зная законы движения планет и имея начальные данные положения планеты в какой то момент времени, можно рассчитать где была или будет планета в любой момент времени. Включая в вычисления все больше законов и информации можно рассчитывать все точнее и дальше во времени. Это тоже знание - ответ на вопрос, где именно сейчас эта планета. Эту идею можно применить практически к любой области знания человека - математика, физика, астрономия, биология, география, социология, предсказание погоды, рынка и так далее.

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

Вычислительный движок Wolfram|Alpha как раз и старается ответить на эти вопросы.
Система использует свои базы данных фактов (как они их называют) и, обрабатывая запрос, пытается именно рассчитать, а не найти ответ в Интернете.

К примеру:
Halley comet
San Francisco to Tokyo
ISS
probability 12 heads 08 tails
continued fraction tan x
Mainz weather

Пока система охватывает лишь наиболее распространенные данные, но уже может давать ответы на совершенно разные вопросы. Система заслуживает похвалы и очень хочется надеятся, что вырастет в нечто покожее на google.

вторник, 10 февраля 2009 г.

Boost 1.38.0

Вот и вышла следующая версия Boost 1.38.0. После беглого взгляда добавили не очень то много, но зато поправили достаточно изрядно. Впрочем для меня интересным введением была библиотека Flyweight. Как раз сейчас пытаюсь применить ее как решение к некоторым задачам. Тесты на производительности и занимаемую память обнадеживают.

Так же интересным введением стала ScopeExit. Достаточно странный макрос на первый взгляд. Обычные смарт-поинтеры при высвобождении делают одну операцию - delete, но как отмечается в документации бывает накладно каждый раз писать класс, который принимает и как-то высвобождает ресурс. К примеру, хендл на файл (закрыть при исключении), хранилище объектов, которое возвращается в предыдущее состояние если какая-либо операция не удалась. Библиотека предлагает обойтись одним лишь макросом, которые встраивается прямо в функцию, которая испольняет какую либу операцию и нуждается в откате, если в ней произошло исключение. Выглядит это примерно так:
void Container::insert(Object const& obj) 
{
bool commit = false;
m_vector.push_back(obj);
BOOST_SCOPE_EXIT( (&commit)(&m_vector) )
{
if(!commit)
m_vector.pop_back();
} BOOST_SCOPE_EXIT_END
// ... other operations ...
commit = true;
}

Здесь макрос создает оббертку прямо внутри функции, которая будет вызвана при выходе из функции в любой случае - через исключение и "нормальным" путем. В эту оббертку он передает ссылки на commit и m_vector, которые можно будет посмотреть/модифицировать при завершении функции. В данном примере, если дело не дошло до commit = true, то внутри BOOST_SCOPE_EXIT совершится откат на один элемент (к примеру исключение было брошено копи-конструктором класса Object). Вот так все просто и незатейливо. Стало даже интересно покопаться и посмотреть как все это реализовано, возможно идиома может быть полезна и в других задачах.

Буду писать далее, по возможности, про новые фичи и чем они могут быть полезны.

четверг, 5 февраля 2009 г.

Superfast Hash function

Если вам необходимо часто хешировать данные/строки, то рекомендую интересную функцию разработанную by Paul Hsieh - SuperFastHash. Она не только быстрее всех стандартных дающих 4 байтовый код, но и имеет неплохое распределение. Я пока с явными коллизиями не сталкивался.

Boost.Assign

Может тема и известна обширно, но не могу не поделиться радостями использования библиотеки Boost.Assign.
Дело в том, что в стандарте С++ не предусмотрено (пока, ждем С++0x) удобное заполнение контейнеров объектами. Как массивы можно заполнять структуры (и то не все):
struct object
{
long value;
};

object data[] = { 10, 20, 30 };

Но если нужно заполнить динамический контейнер как std::vector<> то этот метод здесь не применим. Как раз тут идет на помощь Boost. С помощью нехитрой библиотеки Assign можно делать такое:
std::vector<long> data;
data += 10, 20, 30;

и даже
std::vector<long> v;
std::vector<long> data;
data += repeat(5, 10), repeat(5, 20), range(v.begin(),v.end());

или
std::map<std::string, int> months;  
insert(months)
( "january", 31 )( "february", 28 )
( "march", 31 )( "april", 30 )
( "may", 31 )( "june", 30 )
( "july", 31 )( "august", 31 )
( "september", 30 )( "october", 31 )
( "november", 30 )( "december", 31 );

Когда в проект было не вставить Boost, пришлось сделать нечто подобное, что отлично работало. Я правда добавил побольше генераторов - генерация случайных чисел и вставка сразу в контейнер, генерация последовательностей. Экономит время написания кода, особенно когда нужно забивать векторы отладочными данными, да и визуально виглядит очень читабельно. Использую давно - проблем не было, и всем рекомендую.

В принципе методы использованые в библиотеки могут оказаться полезными и для других нужд. К примеру, существует ядро, которое возвращает объект, а объект в свою очередь имеет контейнер значений который мы хотим заполнить:
DB db;
Object obj = db.get("object");
obj.push_back(10);
obj.push_back(11);
obj.push_back(12);

а можно возвращать промежуточный объект, который в случае чего может быть приведен к объекту Object, и в котором будут переопределены операторы += и , добавляющие данные в объект:
DB db;
db.get("object") += 10, 11, 12;

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

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

Boost.Flyweight

Вчера наткнулся на новую библиотеку, которая будет в новой (1.38) версии Boost. Сейчас ее тестируют и судя по всему все работает неплохо. Ее название Boost.Flyweight (link пока работает, потом документация будет перенесена).

Общая идея проста - создать некий репозиторий, который хранит только уникальные объекты. Вообщем шаблон проектирования так и называется Flyweight, что по русски звучит как "Приспособленец". К примеру, если у вас есть объект буква и вы хотите хранить для нее информацию о шрифте, размере, стилях и т.д, то в итоге даже небольшой текст состоящий из таких букв будет отнимать у системы довольно много ресурсов. Хотя при анализе мы увидим, что в этой информации очень много повторяющихся блоков, которые хорошо было бы организовать таким образом, что хранится только один, а сами буквы имеют только ссылки на этот уникальный блок. Такой механизм наиболее прозрачным образом и реализует Flyweight. 

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

Как это работает все? К примеру у вас есть объект и вам требуется хранить в системе огромное количество его экземпляров:

struct user_entry
{
std::string first_name;
std::string last_name;
int age;
...
};

Очевидно, что имена будут часто повторяться и это требуемое количество памяти можно уменьшить используя Flyweight:

#include <boost/flyweight.hpp>
struct user_entry
{
flyweight <std::string> first_name;
flyweight <std::string> last_name;
int age;
...
};

Эти переменные работают как и обычные переменные, потому и пересывать остальной код нет необходимости (в этом я вижу огромное удобство) - конструкторы, операторы отношения, сериализация... Теперь в системе будет создан некий словарь строк и если будет создан объект с именами, которые уже попадались в системе, то новая память выделена не будет, а будут использованы лишь ссылки.

Осталось только подождать релиза и попробовать на деле.

пятница, 2 января 2009 г.

curr_year = new year(2009); cout << "hello world";

С Новым Годом всем! Пока нет ясных мыслей что же я буду сюда писать, но время покажет. Пока пусть название скажет за себя. 

Кстати название блога навеяно старым уже позабытым творением Щербакова про лесного хакера Винни Пуха: http://lib.ru/ANEKDOTY/9600.txt . Тем кто помнит еще те времена, когда скорость соединения считали в бодах, а EC1840 не выглядел еще таким антиквариатом...