Re[16]: Good practice по алгоритмизации в условиях асинхронн
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 30.08.10 16:03
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

КЛ>>Вы не могли бы конкретизировать, что Вам непонятно?

G>
G>Обновляльщик Цен -> (Таблица Товаров) -> Принимальщик Решений
G>

G>Вот эта цепочка.

Давайте детализируем. Выше
Автор: Кирилл Лебедев
Дата: 26.08.10
я уже приводил псевдокод:

// Принимальщик решений
bool bGo = true;

while (bGo)
{
    Отмена_Текущей_Заявки();
    Подача_Новой_Заявки();
    // ...
    Sleep(TimeToSleep);
}

// Обновляльщик цен
void Обновление_Цен()
{
    bool bGo = true;

    while (bGo)
    {
        Получить_Биржевой_Тик();
        Обновить_Таблицу_Товаров();
        Sleep(TimeToSleep);
    }
}


Что в приведенном псевдокоде Вам непонятно?

КЛ>>Я писал о внешних источниках — не о внутренних.

G>А чем они хуже\лучше внутренних?

Тем, что они доступны в любой момент — под них не надо подстраиваться.

КЛ>>>>(1) либо запустить Принимальщик Решений в отдельном потоке со своей частотой, которая не зависит от частоты поступления событий;

G>>>Плохо, потому что частоты входящих событий не фиксированы.
КЛ>>Чем плохо?
G>Тем что в среднем неэффективно получится, или реакция будет запаздывать, или ресурсы прожигаться будут. Так или иначе масштабируемость ухудшится.
Не думаю. Наоборот, основной цикл программы будет работать с той частотой, которая нам будет нужна, и не будет зависеть от перепадов нагрузки. Поток не зависнет, если по какой-либо причине количество входящих запросов вдруг резко возрастет. В целом, решение получается достаточно надежным и масштабируемым.

КЛ>>Понимаю, что это может сократить код при реализации, но не понимаю, как это влияет на проектирование и на выработку концептуального решения?

G>Потому что вводится новая абстракция (первоклассная сущность) — поток событий.
G>Примерно также при ФП дизайн получается не такой же как при ООП.
Не вижу причин, по которым "поток событий" нельзя описать без привязки с определенной технологии.

Абстрактно: Есть события А, Б и В, которые приходят с разной частотой.

Поток событий делается так: При поступлении каждое событие запоминается в некотором буфере. Далее — если пришло событие А, то берем Б и В из буфера и передаем на обработку. Если пришло Б, то берем А и В и т.д.

Технология тут не при чем. Фактически, получается то же самое, что я и описал при помощи таблиц.

G>Ну мы ведь не об обычных приложениях говорим. Когда начинают возится с асинхронным IO, то рассчитывают на большую нагрузку. И тС привел пример приложений, в которых время реакции очень важно.

На мой взгляд, лучше придерживаться поставленной задачи — иначе уйдем в дебри.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[17]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.08.10 19:24
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, gandjustas, Вы писали:


КЛ>>>Вы не могли бы конкретизировать, что Вам непонятно?

G>>
G>>Обновляльщик Цен -> (Таблица Товаров) -> Принимальщик Решений
G>>

G>>Вот эта цепочка.

КЛ>Давайте детализируем. Выше
Автор: Кирилл Лебедев
Дата: 26.08.10
я уже приводил псевдокод:


КЛ>
КЛ>// Принимальщик решений
КЛ>bool bGo = true;

КЛ>while (bGo)
КЛ>{
КЛ>    Отмена_Текущей_Заявки();
КЛ>    Подача_Новой_Заявки();
КЛ>    // ...
КЛ>    Sleep(TimeToSleep);
КЛ>}

КЛ>// Обновляльщик цен
КЛ>void Обновление_Цен()
КЛ>{
КЛ>    bool bGo = true;

КЛ>    while (bGo)
КЛ>    {
КЛ>        Получить_Биржевой_Тик();
КЛ>        Обновить_Таблицу_Товаров();
КЛ>        Sleep(TimeToSleep);
КЛ>    }
КЛ>}
КЛ>


КЛ>Что в приведенном псевдокоде Вам непонятно?


Понятно все, непонятно как это заставить работать эффективно. Нужен язык вроде Erlang с "зелеными" потоками, в других языках придется "зелень" вручную создавать.

КЛ>>>Я писал о внешних источниках — не о внутренних.

G>>А чем они хуже\лучше внутренних?
КЛ>Тем, что они доступны в любой момент — под них не надо подстраиваться.
Проблемы есть пока считаешь эти потоки разными, как только появляется абстракция, которая позволяет не "подстраиваться" сразу проблемы исчезают.

КЛ>>>>>(1) либо запустить Принимальщик Решений в отдельном потоке со своей частотой, которая не зависит от частоты поступления событий;

G>>>>Плохо, потому что частоты входящих событий не фиксированы.
КЛ>>>Чем плохо?
G>>Тем что в среднем неэффективно получится, или реакция будет запаздывать, или ресурсы прожигаться будут. Так или иначе масштабируемость ухудшится.
КЛ>Не думаю. Наоборот, основной цикл программы будет работать с той частотой, которая нам будет нужна, и не будет зависеть от перепадов нагрузки.
Не понял, выделенное за счет чего будет достигаться? Куда дополнительная нагрузка рассеиваться будет?



КЛ>Поток не зависнет, если по какой-либо причине количество входящих запросов вдруг резко возрастет. В целом, решение получается достаточно надежным и масштабируемым.

Ок, топикстартер приводил здесь код, я его написал в варианте с Rx. Напиши его в своем варианте, просто сравним результаты под нагрузкой.

КЛ>>>Понимаю, что это может сократить код при реализации, но не понимаю, как это влияет на проектирование и на выработку концептуального решения?

G>>Потому что вводится новая абстракция (первоклассная сущность) — поток событий.
G>>Примерно также при ФП дизайн получается не такой же как при ООП.
КЛ>Не вижу причин, по которым "поток событий" нельзя описать без привязки с определенной технологии.
Таких причин собственно и нет. Rx уже портировали на JS и собираются портировать на С++. Сами интерфейсы, описывающие абстракции потоков событий, очень простые. Буквально два интерфейса с 1 и 3 методами. Сила Rx не столько в количестве написанного кода, сколько в том что этот код опирается на строгую математику.

КЛ>Абстрактно: Есть события А, Б и В, которые приходят с разной частотой.

КЛ>Поток событий делается так: При поступлении каждое событие запоминается в некотором буфере. Далее — если пришло событие А, то берем Б и В из буфера и передаем на обработку. Если пришло Б, то берем А и В и т.д.
Меня собственно интересует реализация этой логики "если.., то.." не получился ли куча ифов, от которых старались уйти?

КЛ>Технология тут не при чем. Фактически, получается то же самое, что я и описал при помощи таблиц.

Именно технология причем. Цель известна, ТС привел код. Проблемы также известны — необходиомсть хранить состояние. Я варианты реализации уже привел, их буквально 3 штуки. Теперь можем попробовать на реальном коде оценить достоинства и недостатки каждого из них.

G>>Ну мы ведь не об обычных приложениях говорим. Когда начинают возится с асинхронным IO, то рассчитывают на большую нагрузку. И тС привел пример приложений, в которых время реакции очень важно.

КЛ>На мой взгляд, лучше придерживаться поставленной задачи — иначе уйдем в дебри.
Ну так поставленная задача — написать торгового бота, обычно серьезные торговые стратегии опрерируют кучей событий и работают под большой нагрузкой, поэтому нужна масштабируемость (то есть минимальный порядок роста потребляемых ресурсов при возрастании количества входящих сообщений).
Re[18]: Good practice по алгоритмизации в условиях асинхронн
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 30.08.10 21:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

КЛ>>Что в приведенном псевдокоде Вам непонятно?

G>Понятно все, непонятно как это заставить работать эффективно. Нужен язык вроде Erlang с "зелеными" потоками, в других языках придется "зелень" вручную создавать.

Трудно комментировать оценки. По приведенному коду есть какой-нибудь осмысленный вопрос?

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

G>Не понял, выделенное за счет чего будет достигаться? Куда дополнительная нагрузка рассеиваться будет?
За счет того, что основной цикл будет зависеть от частоты поступающих сообщений. А дополнительная нагрузка будет "рассеиваться":

(1) либо сама собой, когда минует пиковая нагрузка;
(2) либо при помощи потери устаревших сообщений;
(3) либо путем распределения нагрузки между доп. серверами.

В последнем случае у нас будет не один обработчик бизнес-логики, а несколько.

КЛ>>Поток не зависнет, если по какой-либо причине количество входящих запросов вдруг резко возрастет. В целом, решение получается достаточно надежным и масштабируемым.

G>Ок, топикстартер приводил здесь код, я его написал в варианте с Rx. Напиши его в своем варианте, просто сравним результаты под нагрузкой.

У меня нет особого желания переубеждать тебя в чем-то. Высказать свои аргументы я могу, а вот тратить несколько часов (а может и дней) своего времени на написание полностью работающего и отлаженного кода на С++ у меня, честно говоря, нет желания. Но если ты все-таки хочешь убедиться в том, чей вариант будет работать лучше, то предлагаю тебе реализовать оба варианта (и свой, и мой) самому, самостоятельно провести тестирование и сообщить нам о результатах. И мне, и коллегам, полагаю, это будет интересно.

КЛ>>Абстрактно: Есть события А, Б и В, которые приходят с разной частотой.

КЛ>>Поток событий делается так: При поступлении каждое событие запоминается в некотором буфере. Далее — если пришло событие А, то берем Б и В из буфера и передаем на обработку. Если пришло Б, то берем А и В и т.д.
G>Меня собственно интересует реализация этой логики "если.., то.." не получился ли куча ифов, от которых старались уйти?
Нет, не получится. По крайней мере, не будет вложенности условий, и код будет содержать один оператор if.

КЛ>>Технология тут не при чем. Фактически, получается то же самое, что я и описал при помощи таблиц.

G>Именно технология причем. Цель известна, ТС привел код. Проблемы также известны — необходиомсть хранить состояние. Я варианты реализации уже привел, их буквально 3 штуки. Теперь можем попробовать на реальном коде оценить достоинства и недостатки каждого из них.

Технологии постоянно меняются + зависят от платформы и языка. А решая задачу без привязки к технологиям, можно очень легко переносить решения с платформы на платформу. Фактически, благодаря такому подходу мне и моим бывшим коллегам было нетрудно портировать навигационную систему с платформы на платформу, например, с Windows Mobile под Symbian.

КЛ>>На мой взгляд, лучше придерживаться поставленной задачи — иначе уйдем в дебри.

G>Ну так поставленная задача — написать торгового бота, обычно серьезные торговые стратегии опрерируют кучей событий и работают под большой нагрузкой, поэтому нужна масштабируемость (то есть минимальный порядок роста потребляемых ресурсов при возрастании количества входящих сообщений).
Это уже твое предположение (пусть и имеющее некоторые основания). В исходной постановке об этом не было ни слова.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[19]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.08.10 04:05
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, gandjustas, Вы писали:


КЛ>>>Что в приведенном псевдокоде Вам непонятно?

G>>Понятно все, непонятно как это заставить работать эффективно. Нужен язык вроде Erlang с "зелеными" потоками, в других языках придется "зелень" вручную создавать.

КЛ>Трудно комментировать оценки. По приведенному коду есть какой-нибудь осмысленный вопрос?


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

G>>Не понял, выделенное за счет чего будет достигаться? Куда дополнительная нагрузка рассеиваться будет?
КЛ>За счет того, что основной цикл будет зависеть от частоты поступающих сообщений. А дополнительная нагрузка будет "рассеиваться":

КЛ>(1) либо сама собой, когда минует пиковая нагрузка;

Она не минутет. Для торговых систем она в среднем стабильна.

КЛ>(2) либо при помощи потери устаревших сообщений;

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

КЛ>>>Поток не зависнет, если по какой-либо причине количество входящих запросов вдруг резко возрастет. В целом, решение получается достаточно надежным и масштабируемым.

G>>Ок, топикстартер приводил здесь код, я его написал в варианте с Rx. Напиши его в своем варианте, просто сравним результаты под нагрузкой.

КЛ>У меня нет особого желания переубеждать тебя в чем-то. Высказать свои аргументы я могу, а вот тратить несколько часов (а может и дней) своего времени на написание полностью работающего и отлаженного кода на С++ у меня, честно говоря, нет желания. Но если ты все-таки хочешь убедиться в том, чей вариант будет работать лучше, то предлагаю тебе реализовать оба варианта (и свой, и мой) самому, самостоятельно провести тестирование и сообщить нам о результатах. И мне, и коллегам, полагаю, это будет интересно.

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

КЛ>>>Абстрактно: Есть события А, Б и В, которые приходят с разной частотой.

КЛ>>>Поток событий делается так: При поступлении каждое событие запоминается в некотором буфере. Далее — если пришло событие А, то берем Б и В из буфера и передаем на обработку. Если пришло Б, то берем А и В и т.д.
G>>Меня собственно интересует реализация этой логики "если.., то.." не получился ли куча ифов, от которых старались уйти?
КЛ>Нет, не получится. По крайней мере, не будет вложенности условий, и код будет содержать один оператор if.

Те псевдокод такой

Если пришло А
{
    Взять Б. 
    В зависимости от (А,Б) выполнить действие (тоже if)
}
Если пришло Б
{
    Взять А.
    В зависимости от (А,Б) выполнить действие (тоже if).
}


В итоге два ифа, как и у ТС. Также получится два ифа если делать явный автомат.
Что выигрываем?

КЛ>>>Технология тут не при чем. Фактически, получается то же самое, что я и описал при помощи таблиц.

G>>Именно технология причем. Цель известна, ТС привел код. Проблемы также известны — необходиомсть хранить состояние. Я варианты реализации уже привел, их буквально 3 штуки. Теперь можем попробовать на реальном коде оценить достоинства и недостатки каждого из них.

КЛ>Технологии постоянно меняются + зависят от платформы и языка. А решая задачу без привязки к технологиям, можно очень легко переносить решения с платформы на платформу. Фактически, благодаря такому подходу мне и моим бывшим коллегам было нетрудно портировать навигационную систему с платформы на платформу, например, с Windows Mobile под Symbian.

Решение всегда зависит от языка и технологий. Например код на функциональном языке всегда не поход на код на императивном языке.
Более частный пример: отсутствие yield в C++ не позволит эффективно писать итератор, который позволяет выполнять линейный код работать асинхронно.
Другой частный пример: в Silverlight\js все взаимодействие с внешним миром асинхронно, поэтому любителям писать синхронный код надо напрягаться с передачей контекста от места вызова до места обработки.

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

КЛ>>>На мой взгляд, лучше придерживаться поставленной задачи — иначе уйдем в дебри.

G>>Ну так поставленная задача — написать торгового бота, обычно серьезные торговые стратегии опрерируют кучей событий и работают под большой нагрузкой, поэтому нужна масштабируемость (то есть минимальный порядок роста потребляемых ресурсов при возрастании количества входящих сообщений).
КЛ>Это уже твое предположение (пусть и имеющее некоторые основания). В исходной постановке об этом не было ни слова.
Дык топикстартер привел конкретный код.
Re[20]: Good practice по алгоритмизации в условиях асинхронн
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 31.08.10 19:00
Оценка:
Здравствуйте, gandjustas, Вы писали:

КЛ>>(1) либо сама собой, когда минует пиковая нагрузка;

G>Она не минутет. Для торговых систем она в среднем стабильна.
Тогда и не будет проблем с производительностью.

G>ТС привел код, я приводил свой варинат. Писать агенты у меня нет желания.

G>Кроме того я до сих пор не понимаю как будут обрабатываться события и как о них будет узнавать обработчик БЛ.

Обработчик БЛ берет данные из таблиц (их описание см. здесь
Автор: Кирилл Лебедев
Дата: 25.08.10
). Он может "тупо" раз в определенное время "просыпаться", выполнять БЛ, а затем — "засыпать". Но можно его "пробуждение" приурочивать и к биржевому тику, как я писал выше.

Собственно говоря, об этом я уже писал выше не один раз.

G>Те псевдокод такой


G>
G>Если пришло А
G>{
G>    Взять Б. 
G>    В зависимости от (А,Б) выполнить действие (тоже if)
G>}
G>Если пришло Б
G>{
G>    Взять А.
G>    В зависимости от (А,Б) выполнить действие (тоже if).
G>}
G>


G>В итоге два ифа, как и у ТС. Также получится два ифа если делать явный автомат.

G>Что выигрываем?

Нет, код будет совсем другой. Выше
Автор: Кирилл Лебедев
Дата: 26.08.10
я уже приводил пример ветвистого кода:

if (A)
{
    if (B)
    {
        if (!C)
            do1();

        do2();
    }
    else
    {
        if (C)
           do1();
        else
            do3();

        do4();
    }
}
else
{
    if (B)
    {
        if (!C)
            do1();

        do5();
    }
    else
    {
        if (C)
            do1();
        else
            do6();

        do2();
    }
}


Чтобы избавиться от ветвистости, нужно выполнить такой алгоритм:

Шаг 1.Сгруппировать условия по действиям.
Т.е. к каждой функции приписать условия, при которых она выполняется, индивидуально.

Получится:

if (A && B && !C || A && !B && C || !A && B && !C || !A && !B && C)
    do1();

if (!A && !B && !C)
    do6();

if (A && B || !A && !B)
    do2();

if (A && !B && !C)
    do3();

if (A && !B)
    do4();

if (!A && B)
    do5();


Шаг 2. Упростить логические выражения.

Получим:

if (B != С)
    do1();

if (!A && !B && !C)
    do6();

if (A == B)
    do2();

if (A && !B && !C)
    do3();

if (A && !B)
    do4();

if (!A && B)
    do5();


Теперь стало понятнее?
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[21]: Good practice по алгоритмизации в условиях асинхронн
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.08.10 19:15
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, gandjustas, Вы писали:


КЛ>>>(1) либо сама собой, когда минует пиковая нагрузка;

G>>Она не минутет. Для торговых систем она в среднем стабильна.
КЛ>Тогда и не будет проблем с производительностью.
Проблемы с производительность для торговых систем тоже стабильны

G>>ТС привел код, я приводил свой варинат. Писать агенты у меня нет желания.

G>>Кроме того я до сих пор не понимаю как будут обрабатываться события и как о них будет узнавать обработчик БЛ.

КЛ>Обработчик БЛ берет данные из таблиц (их описание см. здесь
Автор: Кирилл Лебедев
Дата: 25.08.10
). Он может "тупо" раз в определенное время "просыпаться", выполнять БЛ, а затем — "засыпать". Но можно его "пробуждение" приурочивать и к биржевому тику, как я писал выше.

КЛ>Собственно говоря, об этом я уже писал выше не один раз.
Ага, а теперь сами события. Как они будут попадать в таблицы? (как понимаю это будут очереди на самом деле, терять то нельзя).

G>>Те псевдокод такой


G>>
G>>Если пришло А
G>>{
G>>    Взять Б. 
G>>    В зависимости от (А,Б) выполнить действие (тоже if)
G>>}
G>>Если пришло Б
G>>{
G>>    Взять А.
G>>    В зависимости от (А,Б) выполнить действие (тоже if).
G>>}
G>>


G>>В итоге два ифа, как и у ТС. Также получится два ифа если делать явный автомат.

G>>Что выигрываем?

КЛ>Нет, код будет совсем другой. Выше
Автор: Кирилл Лебедев
Дата: 26.08.10
я уже приводил пример ветвистого кода:


КЛ>
КЛ>if (A)
КЛ>{
КЛ>    if (B)
КЛ>    {
КЛ>        if (!C)
КЛ>            do1();

КЛ>        do2();
КЛ>    }
КЛ>    else
КЛ>    {
КЛ>        if (C)
КЛ>           do1();
КЛ>        else
КЛ>            do3();

КЛ>        do4();
КЛ>    }
КЛ>}
КЛ>else
КЛ>{
КЛ>    if (B)
КЛ>    {
КЛ>        if (!C)
КЛ>            do1();

КЛ>        do5();
КЛ>    }
КЛ>    else
КЛ>    {
КЛ>        if (C)
КЛ>            do1();
КЛ>        else
КЛ>            do6();

КЛ>        do2();
КЛ>    }
КЛ>}
КЛ>


КЛ>Чтобы избавиться от ветвистости, нужно выполнить такой алгоритм:


КЛ>Шаг 1.Сгруппировать условия по действиям.

КЛ>Т.е. к каждой функции приписать условия, при которых она выполняется, индивидуально.

КЛ>Получится:


КЛ>
КЛ>if (A && B && !C || A && !B && C || !A && B && !C || !A && !B && C)
КЛ>    do1();

КЛ>if (!A && !B && !C)
КЛ>    do6();

КЛ>if (A && B || !A && !B)
КЛ>    do2();

КЛ>if (A && !B && !C)
КЛ>    do3();

КЛ>if (A && !B)
КЛ>    do4();

КЛ>if (!A && B)
КЛ>    do5();
КЛ>


КЛ>Шаг 2. Упростить логические выражения.


КЛ>Получим:


КЛ>
КЛ>if (B != С)
КЛ>    do1();

КЛ>if (!A && !B && !C)
КЛ>    do6();

КЛ>if (A == B)
КЛ>    do2();

КЛ>if (A && !B && !C)
КЛ>    do3();

КЛ>if (A && !B)
КЛ>    do4();

КЛ>if (!A && B)
КЛ>    do5();
КЛ>


КЛ>Теперь стало понятнее?


Конечно, это чисто механическое действие, но ТС говорил вообще-то о другом. Я немного знаком с асинхронным программированием и знаю как громоздко выглядит нелинейный асинхронный код. Тем не менее все сводится к автомату, который реализуется ифами двух уровней (а может и одним — селектором верхнего уровня служит само событие).

А вот выкрутить в обратную сторону, как ты предлагаешь, довольно проблематично. Условие "наступило событие А текущее состояние 1 или наступило событие Б и текущее событие 2" простым способом не запишешь. Потому что событие — это push, а проверка в ифе — pull. Вот и приходится платить довольно высокую цену — создавать очереди, плодить потоки итп, только чтобы из полутора вложенных ифов получить один. Это не только хуже работает, но и сложнее сопровождается.
Re[29]: Good practice по алгоритмизации в условиях асинхронн
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.09.10 11:07
Оценка:
Здравствуйте, Undying, Вы писали:

U>Что значит асинхронно? В смысле в другом потоке? Ну так поставь таску на чтение файла в другой поток, а не в основной и будет тебе счастье.


налицо трагическое непонимание. Нет никакого "другого потока". В IOCP чтение выполняет не поток, а, грубо говоря, контроллер ввода-вывода. Именно в этом принципиальная разница. Тратить мегабайт стека только на то, чтобы он спал в ожидании контроллера — бессмысленное расточительство. С биржей всё будет ещё хуже: скажем, три тысячи отслеживаемых тикеров просто не влезут в 32хразрядное адресное пространство, если каждому выделять свой поток. Не говоря уже о том, что накладные расходы на пробуждение такого потока тоже весьма отличны от нуля.
Код, построенный на основе IOCP, может одновременно ждать сотни тысяч тикеров без заметного роста нагрузки на CPU и память. А это важно — меньше шансов попасть в своп, из которого долго подниматься при приходе долгожданного события.
При этом собственно время обработки события пренебрежимо мало — процессору достаточно наносекунд, чтобы выполнить все вычисления и принять торговое решение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[31]: Good practice по алгоритмизации в условиях асинхронн
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.09.10 11:09
Оценка:
Здравствуйте, Undying, Вы писали:

U>А асинхронная операция в ОС она магическая или как? Ни потоков, ни процессорного времени не использует?

Совершенно верно. Она магическая. Зачем, к примеру, тратить процессорное время и/или потоки на ожидание приезда пакета в сетевую карту? Там внутри достаточно оборудования, чтобы всё сделать без нас.
Вот когда данные приехали, можно и сообщить в пользовательский код, что пора за работу. Именно так и работают современные высокопроизводительные приложения.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Good practice по алгоритмизации в условиях асинхронно
От: sergunok  
Дата: 14.09.10 21:34
Оценка:
Бороться со сложностью можно используя иерархические КА, в которых состояние само может быть КА.

Но "надрыв мозга" при составлении КА конечно же будет.

Кстати исходный "линейный" алгоритм (из того разряда, который я приводил в примере) отчасти так или иначе в явном виде содержит КА, поскольку состоит из:
1. Описаний последовательностей команд и проверяемых условий при приходе тех или иных событий
2. Описание своего рода "синхронизации" действий, т.е. что делать если в момент прихода события, на которое нужно реагировать, уже выполняется какое-то действие..

Честно говоря, по п.2 не вижу более естественного и популярного пути описания этой логики, чем КА.



Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, asimonenko, Вы писали:


A>>Все равно все сведется к автомату, ИМХО. Т.е. данные появляются асинхронно, и при определенных условиях (наборе данных) ты должен выполнить определенное действие.


A>>То же самое с сериализацией — при десериализации ты логично "двигаешь" автомат в нужную точку последовательностью входящих данных.


A>>Словом, КА — просто и надежно. Только его нужно сразу выявить, формализовать (куда-нибудь записать диаграммку) и реализовать на ранних стадиях, пока не наворочена неформализованная куча -)


G>Для автоматов нет способов борьбы со сложностью. Если состояний станет слишком много, то не не будет возможности как-то исправить.
Re[4]: Good practice по алгоритмизации в условиях асинхронно
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 15.09.10 11:07
Оценка:
Здравствуйте, sergunok, Вы писали:

S>Бороться со сложностью можно используя иерархические КА, в которых состояние само может быть КА.


S>Но "надрыв мозга" при составлении КА конечно же будет.


S>Кстати исходный "линейный" алгоритм (из того разряда, который я приводил в примере) отчасти так или иначе в явном виде содержит КА, поскольку состоит из:

S>1. Описаний последовательностей команд и проверяемых условий при приходе тех или иных событий
S>2. Описание своего рода "синхронизации" действий, т.е. что делать если в момент прихода события, на которое нужно реагировать, уже выполняется какое-то действие..

S>Честно говоря, по п.2 не вижу более естественного и популярного пути описания этой логики, чем КА.


Это теория, на практике автомат с нетривиильной логикой в котором более 10 состояний и от каждого более одного перехода — получается страшный макаронный код, который очень тяжело поддерживать. Все потому что нету у КА средств борьбы со сложностьюю
Re[3]: Good practice по алгоритмизации в условиях асинхронно
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 24.09.10 17:24
Оценка:
Здравствуйте, Aviator, Вы писали:

A>Здравствуйте, gandjustas, Вы писали:


G>>Смотри Rx

A>Давно интересовался практическими применениями этой либы, может есть у кого случаи успешного применения в рабочих проектах?

Мне очень туго пришлось бы в последнем проекте без этой штуки. Особенно выручает в ситуациях, когда возникает необходимость отправить сервису команду А, асинхронно получить результат, потом на его сформировать команду Б ..., потом проделать тоже самое со следующим сервисом, и так далее, и так далее, а если в процессе произойдет ошибка, то послать первому сервису команду ...
Re[4]: Good practice по алгоритмизации в условиях асинхронно
От: sergunok  
Дата: 24.09.10 17:54
Оценка:
Здравствуйте, Lazin, Вы писали:

L>Здравствуйте, Aviator, Вы писали:


A>>Здравствуйте, gandjustas, Вы писали:


G>>>Смотри Rx

A>>Давно интересовался практическими применениями этой либы, может есть у кого случаи успешного применения в рабочих проектах?

L>Мне очень туго пришлось бы в последнем проекте без этой штуки. Особенно выручает в ситуациях, когда возникает необходимость отправить сервису команду А, асинхронно получить результат, потом на его сформировать команду Б ..., потом проделать тоже самое со следующим сервисом, и так далее, и так далее, а если в процессе произойдет ошибка, то послать первому сервису команду ...


Может быть приведешь примерчик кода того применения, которое порадоволо?
Re[5]: Good practice по алгоритмизации в условиях асинхронно
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 25.09.10 13:18
Оценка:
Здравствуйте, sergunok, Вы писали:

S>Может быть приведешь примерчик кода того применения, которое порадоволо?


Почему бы и нет. Вот это:
        public IObservable<IList<OIValue>> CategoryUpdates(OICategory cat)
        {
            var query = m_connection.QueryUpdateAsync(cat, ...);
            var result = Observable.Create<IList<OIValue>>(
                obsrv =>
                {
                    query.OnCode += (code, q) =>
                        {
                            if (code != 0)
                                obsrv.OnError(new Exception("... error: " + code));
                        };
                    query.OnData += (data, q) =>
                        {
                            obsrv.OnNext(data); 
                        };
                    return () => query.End(); 
                });
            query.Start();
            return result;
        }

порадовало легкостью, с которой некая библиотека доступа к данным, не следующая общепринятым паттернам, может быть использована вместе с Rx. Здесь выполняется подписка на изменение данных, поступающих из некоего хранилища, query — запрос на подписку, OnCode — вызывается при возникновении разных ошибок, OnData — при появлении новых данных, Start — выполняет запрос, End — отменяет подписку. Все это безобразие приводится к интерфейсу IObservable с минимальными усилиями, без необходимости написания кучи boilerplate кода.
Но больше всего радует конечно же возможность комбинировать разные IObservable объекты.
Вот такой код, к примеру, у меня отвечает за отображение текущего состояния некоего объекта:
            var attachments = new List<IDisposable>()
            {
                Observable.Merge(
                    Suite.SuiteOK(SuiteDetails).Select(x => Tuple.Create(AttentionLevelEnum.OK, x.Item1, x.Item2)),
                    Suite.SuiteWarning(SuiteDetails).Select(x => Tuple.Create(AttentionLevelEnum.Warning, x.Item1, x.Item2)),
                    Suite.SuiteError(SuiteDetails).Select(x => Tuple.Create(AttentionLevelEnum.Error, x.Item1, x.Item2)))
                    .ObserveOn(this)
                    .Subscribe(
                        item => 
                        {
                            ... Update UI State ...
                        }),
            };

            this.HandleDestroyed += (s, evt) => attachments.ForEach(elem => elem.Dispose());

Если бы я не использовал Rx, то пришлось бы создавать объект — конечный автомат, который бы в ответ на события изменял свое состояние и сам был бы источником событий для пользовательского интерфейса. А здесь — все в одном месте, никакого явного состояния, хотя конечно, детали того как происходит подписка на те или иные события, спрятана в ф-ях SuiteXXX, но эти детали и не нужны коду, отвечающему за пользовательский интерфейс
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.