Re[37]: cppcms
От: Evgeny.Panasyuk Россия  
Дата: 25.09.14 10:23
Оценка: 3 (2)
Здравствуйте, artelk, Вы писали:

EP>>В C#, кстати, тоже возможна подобная ситуация — например какой-нибудь ресурс, типа файла, привязан к некоторому scope, через using, и в этом scope запускается async метод который работает с этим файлом, причём переживает вызвавший его scope в другом потоке.

A>Если стоит await, то не переживет. Разве что специально что-то сделать чтоб пережил...

С корутинами такая же ситуация.

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


Зависит от использования. Иногда, например, может понадобится сделать "вилку", и создать новую корутину внизу call-tree.
Но, напомню, что обсуждаемая проблема может возникнуть только если хранить стэк корутины как буфер в создающем её стэке, что как правило не так, и буфер под стэк всё же выделяется динамически (если корутин сотни тысяч, то из специального аллокатора/пула, например
Автор: Evgeny.Panasyuk
Дата: 30.11.13
).

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

A>Давай опишу чего хотелось бы добиться:
A>
A>async Task<int> GetResult()//запускается из IOCP потока
A>{
A>...
A>}
A>


Вот пример по мотивам await_emu
Автор: Evgeny.Panasyuk
Дата: 03.07.13
:
Имеются два потока, "main" и "worker", стартовая точка — функция entry_point, которая запускается в потоке "main".
entry_point создаёт N корутин, которые выполняют несколько асинхронных операций и await'ят их.
Одна из операций — some_async_operation, которая делает какую-то работу (например IO).
Вторая операция — post_task, отправляет задачу на выполнение в заданный контекст (в данном примере в worker_context).
По умолчанию, await возвращается в main_context, но точку возврата для текущей корутины можно поменять через switch_context_to. В данном примере, часть корутин после выполнения задания worker_context'ом "просыпается" в нём же.
В итоге, entry_point выводит результат работы каждой корутины.
// GOTO entry_point

int bar(int i)
{
    print("bar{A}, arg=", i);
    
    if(i/10 % 2 == 1)
        switch_context_to(worker_context);

    // await is not limited by "one level" as in C#    
    auto result = await post_task(worker_context, [i]
    {
        print("inside task, arg=", i);
        return (i+1)*(i+2);
    });

    print("bar{B}");
    return result;
}

int foo(int i)
{
    print("foo{A}, arg=", i);
    await some_async_operation();
    print("foo{B}");
    auto result = bar(i);
    print("foo{C}");
    return result;
}
ASYNC_PREFIX(foo)

void entry_point()
{
    constexpr auto N = 2;
    print("entry_point{A}");

    vector<future<int>> fs;
    for(auto i=0; i!=N; ++i)
    {
        fs.push_back( async_foo((i+1)*10) );
        // Alternative:
        //  fs.push_back( asynchronous([i]{ return foo((i+1)*10); }) );
    }

    print("entry_point{B}");
    for(auto &&f : fs)
        print("Result=", await f);
    print("entry_point{C}");
}

LIVE DEMO
Вывод N=2 (для удобства TID worker'а выделен жирным):
Thread ID=7fe0cff85700 Coro ID=0:    entry_point{A}
Thread ID=7fe0cff85700 Coro ID=1:    foo{A}, arg=10
Thread ID=7fe0cff85700 Coro ID=2:    foo{A}, arg=20
Thread ID=7fe0cff85700 Coro ID=0:    entry_point{B}
Thread ID=7fe0cff85700 Coro ID=1:    foo{B}
Thread ID=7fe0cff85700 Coro ID=1:    bar{A}, arg=10
Thread ID=7fe0cf784700 Non-Coro:    inside task, arg=10
Thread ID=7fe0cf784700 Coro ID=1:    bar{B}
Thread ID=7fe0cf784700 Coro ID=1:    foo{C}
Thread ID=7fe0cff85700 Coro ID=0:    Result=132
Thread ID=7fe0cff85700 Coro ID=2:    foo{B}
Thread ID=7fe0cff85700 Coro ID=2:    bar{A}, arg=20
Thread ID=7fe0cf784700 Non-Coro:    inside task, arg=20
Thread ID=7fe0cff85700 Coro ID=2:    bar{B}
Thread ID=7fe0cff85700 Coro ID=2:    foo{C}
Thread ID=7fe0cff85700 Coro ID=0:    Result=462
Thread ID=7fe0cff85700 Coro ID=0:    entry_point{C}

Как видно, корутина с ID=1 после post_task продолжила своё выполнение в потоке "worker", в то время как корутина с ID=2 — в потоке "main".

  Вывод для N=8
http://coliru.stacked-crooked.com/a/836a2f630d6109be
Thread ID=7f74b4007700 Coro ID=0:    entry_point{A}
Thread ID=7f74b4007700 Coro ID=1:    foo{A}, arg=10
Thread ID=7f74b4007700 Coro ID=2:    foo{A}, arg=20
Thread ID=7f74b4007700 Coro ID=3:    foo{A}, arg=30
Thread ID=7f74b4007700 Coro ID=4:    foo{A}, arg=40
Thread ID=7f74b4007700 Coro ID=5:    foo{A}, arg=50
Thread ID=7f74b4007700 Coro ID=6:    foo{A}, arg=60
Thread ID=7f74b4007700 Coro ID=7:    foo{A}, arg=70
Thread ID=7f74b4007700 Coro ID=8:    foo{A}, arg=80
Thread ID=7f74b4007700 Coro ID=0:    entry_point{B}
Thread ID=7f74b4007700 Coro ID=8:    foo{B}
Thread ID=7f74b4007700 Coro ID=8:    bar{A}, arg=80
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=80
Thread ID=7f74b4007700 Coro ID=6:    foo{B}
Thread ID=7f74b4007700 Coro ID=6:    bar{A}, arg=60
Thread ID=7f74b4007700 Coro ID=8:    bar{B}
Thread ID=7f74b4007700 Coro ID=8:    foo{C}
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=60
Thread ID=7f74b4007700 Coro ID=6:    bar{B}
Thread ID=7f74b4007700 Coro ID=6:    foo{C}
Thread ID=7f74b4007700 Coro ID=1:    foo{B}
Thread ID=7f74b4007700 Coro ID=1:    bar{A}, arg=10
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=10
Thread ID=7f74b3806700 Coro ID=1:    bar{B}
Thread ID=7f74b3806700 Coro ID=1:    foo{C}
Thread ID=7f74b4007700 Coro ID=0:    Result=132
Thread ID=7f74b4007700 Coro ID=5:    foo{B}
Thread ID=7f74b4007700 Coro ID=5:    bar{A}, arg=50
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=50
Thread ID=7f74b3806700 Coro ID=5:    bar{B}
Thread ID=7f74b3806700 Coro ID=5:    foo{C}
Thread ID=7f74b4007700 Coro ID=4:    foo{B}
Thread ID=7f74b4007700 Coro ID=4:    bar{A}, arg=40
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=40
Thread ID=7f74b4007700 Coro ID=4:    bar{B}
Thread ID=7f74b4007700 Coro ID=4:    foo{C}
Thread ID=7f74b4007700 Coro ID=7:    foo{B}
Thread ID=7f74b4007700 Coro ID=7:    bar{A}, arg=70
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=70
Thread ID=7f74b3806700 Coro ID=7:    bar{B}
Thread ID=7f74b3806700 Coro ID=7:    foo{C}
Thread ID=7f74b4007700 Coro ID=3:    foo{B}
Thread ID=7f74b4007700 Coro ID=3:    bar{A}, arg=30
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=30
Thread ID=7f74b3806700 Coro ID=3:    bar{B}
Thread ID=7f74b3806700 Coro ID=3:    foo{C}
Thread ID=7f74b4007700 Coro ID=2:    foo{B}
Thread ID=7f74b4007700 Coro ID=2:    bar{A}, arg=20
Thread ID=7f74b3806700 Non-Coro:    inside task, arg=20
Thread ID=7f74b4007700 Coro ID=2:    bar{B}
Thread ID=7f74b4007700 Coro ID=2:    foo{C}
Thread ID=7f74b4007700 Coro ID=0:    Result=462
Thread ID=7f74b4007700 Coro ID=0:    Result=992
Thread ID=7f74b4007700 Coro ID=0:    Result=1722
Thread ID=7f74b4007700 Coro ID=0:    Result=2652
Thread ID=7f74b4007700 Coro ID=0:    Result=3782
Thread ID=7f74b4007700 Coro ID=0:    Result=5112
Thread ID=7f74b4007700 Coro ID=0:    Result=6642
Thread ID=7f74b4007700 Coro ID=0:    entry_point{C}
  full code
// Copyright Evgeny Panasyuk 2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// e-mail: E?????[dot]P???????[at]gmail.???

// Full emulation of await feature from C# language in C++ based on Stackful Coroutines from
// Boost.Coroutine library.
// This proof-of-concept shows that exact syntax of await feature can be emulated with help of
// Stackful Coroutines, demonstrating that it is superior mechanism.
// Main aim of this proof-of-concept is to draw attention to Stackful Coroutines.

// https://github.com/panaseleus/await_emu
// http://rsdn.ru/forum/cpp/5219587.flat

// GOTO entry_point

#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE

#include <boost/coroutine/all.hpp>
#include <boost/optional.hpp>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>

#include <initializer_list>
#include <functional>
#include <iostream>
#include <cstddef>
#include <utility>
#include <cstdlib>
#include <memory>
#include <vector>
#include <stack>
#include <queue>
#include <ctime>

using namespace std;
using namespace boost;

// ___________________________________________________________ //
template<typename T>
class concurrent_queue
{
    queue<T> q;
    boost::mutex m;
    boost::condition_variable c;
public:
    template<typename U>
    void push(U &&u)
    {
        auto &&l = make_lock_guard(m);
        q.push( forward<U>(u) );
        c.notify_one();
    }
    void pop(T &result)
    {
        boost::unique_lock<boost::mutex> u(m);
        c.wait(u, [&]{return !q.empty();} );
        result = move_if_noexcept(q.front());
        q.pop();
    }
};
// ___________________________________________________________ //
template<typename F>
class Worker
{
    using Job = boost::optional<F>;
    concurrent_queue<Job> q;
    boost::thread worker;
public:
    Worker()  : worker{[this]
                {
                    Job j;
                    while(true)
                    {
                        q.pop(j);
                        if(!j) break;
                        (*j)();
                    }
                }}
    {}
    void finish()
    {
        q.push(Job{});
    }
    void operator()(F &&f)
    {
        q.push(Job{std::move(f)});
    }
    ~Worker()
    {
        worker.join();
    }
    Worker(Worker&&)=delete;
    Worker &operator=(Worker&&)=delete;
};
// ___________________________________________________________ //
using Task = std::function<void()>;
using TaskQueue = Worker<Task>;

using Context = TaskQueue*;
Context default_context{};
Context main_context{};
Context worker_context{};

template<typename F>
auto post_task(Context context, F f)
{
    // same rationale as in asynchronous
    auto result_promise = make_shared<promise<decltype(f())>>(); 
    auto result_future = result_promise->get_future();

    (*context)([result_promise=std::move(result_promise), f=std::move(f)]() mutable
    {
        result_promise->set_value( f() );
    });
    return result_future;
}
// ___________________________________________________________ //
using coro_pull = coroutines::symmetric_coroutine<void>::call_type;
using coro_push = coroutines::symmetric_coroutine<void>::yield_type;

struct CurrentCoro
{
    std::shared_ptr<coro_pull> resume;
    unsigned id;
    TaskQueue *context;
    coro_push *yield;
};

thread_local stack<CurrentCoro> coro_stack;
atomic<unsigned> total_coro_counter;

void switch_context_to(Context context)
{
    coro_stack.top().context = context;
}
// ___________________________________________________________ //
template<typename F>
auto asynchronous(F f)
{
    promise<decltype(f())> coro_promise;
    auto coro_future = coro_promise.get_future();

    // It is possible to avoid shared_ptr and use move-semantic,
    //     but it would require to refuse use of std::function (it requires CopyConstructable),
    //     and would lead to further complication and is unjustified
    //     for purposes of this proof-of-concept
    CurrentCoro current_coro =
    {
        make_shared<coro_pull>([f, coro_promise=std::move(coro_promise)](auto &caller) mutable
        {
            coro_stack.top().yield = &caller;
            coro_promise.set_value( f() );
        }),
        total_coro_counter++,
        default_context
    };

    coro_stack.push( std::move(current_coro) );
    (*coro_stack.top().resume)();
    coro_stack.pop();

    return coro_future;
}

struct Awaiter
{
    template<typename Future>
    auto operator*(Future &&ft) const
    {
        auto &&current_coro = coro_stack.top();
        auto result = ft.then([current_coro](auto ready_future)
        {
            (*current_coro.context)([current_coro]
            {
                coro_stack.push(std::move(current_coro));
                (*coro_stack.top().resume)();
                coro_stack.pop();
            });
            return ready_future.get();
        });
        (*coro_stack.top().yield)();
        return result.get();
    }
};

#define ASYNC_PREFIX(func) \
template<typename ...Args> \
auto async_##func(Args... args) \
{ \
    return asynchronous([=]() mutable \
    { \
        return func(args...); \
    }); \
} \
/**/

#define await Awaiter()*
// ___________________________________________________________ //
void entry_point();

int main()
{
    srand(time(0));

    // Custom scheduling is not required - can be integrated
    // to other systems transparently
    TaskQueue main_tasks, worker_tasks;

    default_context = &main_tasks;
    main_context = &main_tasks;
    worker_context = &worker_tasks;

    main_tasks([&]{asynchronous([&]
    {
        entry_point();

        main_tasks.finish();
        worker_tasks.finish();
        return true;
    });});
}
// __________________________________________________________________ //
template<typename ...Args>
void print(Args... args)
{   
    static boost::mutex m;
    auto &&l = make_lock_guard(m);

    cout << "Thread ID=" << this_thread::get_id();
    if(!coro_stack.empty())
        cout << " Coro ID=" << coro_stack.top().id;
    else
        cout << " Non-Coro";
    cout << ":\t";
    initializer_list<bool>{((cout << args), true)...};
    cout << endl;
}

void reschedule()
{
    boost::this_thread::sleep_for(boost::chrono::milliseconds( rand() % 2000 ));
}

auto some_async_operation()
{
    return async([]{ return reschedule(), 1; });
}
// __________________________________________________________________ //
// __________________________________________________________________ //
// __________________________________________________________________ //
int bar(int i)
{
    print("bar{A}, arg=", i);
    
    if(i/10 % 2 == 1)
        switch_context_to(worker_context);

    // await is not limited by "one level" as in C#    
    auto result = await post_task(worker_context, [i]
    {
        print("inside task, arg=", i);
        return (i+1)*(i+2);
    });

    print("bar{B}");
    return result;
}

int foo(int i)
{
    print("foo{A}, arg=", i);
    await some_async_operation();
    print("foo{B}");
    auto result = bar(i);
    print("foo{C}");
    return result;
}
ASYNC_PREFIX(foo)

void entry_point()
{
    constexpr auto N = 2;
    print("entry_point{A}");

    vector<future<int>> fs;
    for(auto i=0; i!=N; ++i)
    {
        fs.push_back( async_foo((i+1)*10) );
        // Alternative:
        //  fs.push_back( asynchronous([i]{ return foo((i+1)*10); }) );
    }

    print("entry_point{B}");
    for(auto &&f : fs)
        print("Result=", await f);
    print("entry_point{C}");
}


Данный await может ждать любую асинхронную операцию которая принимает continuation (например future.then), и как-то отдельно рассматривать случай с семафором нет необходимости

A>Хотелось бы увидеть образцово-показательный код на С++, чтобы в качестве сервисного метода было, например, что-то вроде такого:

A>
A>async Task<byte[]> GetValue(byte[] bytes)//bytes - пришедшие от клиента данные
A>{
A>...
A>}
A>

A>На сколько реализуемо?

Не пойму что концептуально нового добавляет этот пример по сравнению с предыдущим.
Re[32]: cppcms
От: Ночной Смотрящий Россия  
Дата: 25.09.14 10:56
Оценка:
Здравствуйте, alex_public, Вы писали:

НС>>Это и есть цитирование, только через зад.

_>Как раз это нормальный вариант, т.к. работает во время компиляции, а не исполнения.

Цитирование кода работает во время компиляции. И даже заранее скомпилировать запросы часть провайдеров позволяет. Наконец сама забота об ускорении на доли секунды стартапа серверных приложений отдает шериданством.

НС>>Чего он заинлайнит? Процитированный код? Нахрена?

_>Типа быстродействие не нужно? )

Какое быстродействие? Компилятор ЯП ничего не знает про SQL или какой то другой EDSL, поэтому от его оптимизаций может произойти что угодно, от замедления до полной невозможности построить запрос.

_>Типа все ORM — это зло? )


Не все, только те которые пытаются натянуть сову на глобус,т.е. пытаются работать с БД как будто это объекты в памяти. Потому что эта абстракция страшно течет.

НС>>Ну или я твое сумбурное описание задачи не понял.

_>Естественно всё статически — как-то ты забываешь мою "специализацию". )))

Понимания не добавило.

_>Простейший тестовый пример того, о чём я тут сейчас говорил, можно увидеть здесь http://rsdn.ru/forum/philosophy/5369287
Автор: alex_public
Дата: 21.11.13


Не увидел там ничего, что не умеет линк. Более того, конкретно для линка вообще проблемы со чего то там с чем то нет — потому что он умеет анонимные типы, т.е. тип кортежа выводится по месту, прямо в запросе.

_> Но подразумевается что на практике Person — это не такая простая вещь, а какой-то чужой класс с кучей предков и всяких лишних (в смысле БД) полей.


Вот поэтому рулят анонимные типы. Ну и лишние в смысле БД поля, к тому же, грубейшее нарушение SRP.
Re[33]: cppcms
От: Evgeny.Panasyuk Россия  
Дата: 25.09.14 11:30
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>Это и есть цитирование, только через зад.

_>>Как раз это нормальный вариант, т.к. работает во время компиляции, а не исполнения.
НС>Цитирование кода работает во время компиляции.

А непосредственно разбор деревьев выражений (пусть и сгенерированных в compile-time)?

НС>И даже заранее скомпилировать запросы часть провайдеров позволяет.


Вся работа будет выполнена на этапе сборки проекта, до всякого запуска приложения? Покажи пример такого провайдера.

НС>Наконец сама забота об ускорении на доли секунды стартапа серверных приложений отдает шериданством.


Это только если рассматривать одно из конкретных применений цитирования.

НС>>>Чего он заинлайнит? Процитированный код? Нахрена?

_>>Типа быстродействие не нужно? )
НС>Какое быстродействие? Компилятор ЯП ничего не знает про SQL или какой то другой EDSL, поэтому от его оптимизаций может произойти что угодно, от замедления до полной невозможности построить запрос.

EDSL оптимизирует не компилятор, а библиотека, в compile-time Компилятор оптимизирует результат работы библиотеки, а не сам EDSL
Re[36]: cppcms
От: Privalov  
Дата: 25.09.14 11:39
Оценка:
Здравствуйте, genre, Вы писали:

G>Ну так "у меня все работает" не отменяет того, что у одного все хорошо, у другого плохо, да и вон сколько проблем в коде страницы уже нашли.


Ты так говоришь, как будто я этого не знаю. Но обычно так говорят о своем коде, а я — о чужом. И, как я понял, еще у кого-то та же ситуация, что и у меня. Просто Sheridan-у головняка добавилось. Ведь то, что у меня все нормально, не отменяет твоих результатов.
Re[3]: cppcms
От: 0BD11A0D  
Дата: 25.09.14 12:12
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Профит да, в высоконагруженных. Но не только. Еще есть вариант не тратиться на железо, а запустить на том, что есть, то есть несколько менее требовательное к железу приложение получится. Понятное дело, что как правило на БД основная нагрузка, ну так можно на сервак БД денег больше потратить, а на сервак с веб-приложением — меньше.


Не у всех под рукой есть лохи, которые знают C++ и которые с зарплатой, написанием, поддержкой и всем говном дешевле, чем просто еще один сервер в стойку.
Re[34]: cppcms
От: Ночной Смотрящий Россия  
Дата: 25.09.14 12:15
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

НС>>Цитирование кода работает во время компиляции.

EP>А непосредственно разбор деревьев выражений (пусть и сгенерированных в compile-time)?

По желанию. Можно в рантайме, можно специальной тулзой во время компиляции. Для серверного софта этот вопрос абсолютно непринципиален.

НС>>И даже заранее скомпилировать запросы часть провайдеров позволяет.

EP>Вся работа будет выполнена на этапе сборки проекта, до всякого запуска приложения?

Да.

EP> Покажи пример такого провайдера.


bltoolkit.

НС>>Какое быстродействие? Компилятор ЯП ничего не знает про SQL или какой то другой EDSL, поэтому от его оптимизаций может произойти что угодно, от замедления до полной невозможности построить запрос.

EP>EDSL оптимизирует не компилятор, а библиотека

Коллега утверждал что компилятор.
Re[4]: cppcms
От: Sheridan Россия  
Дата: 25.09.14 12:25
Оценка:
Здравствуйте, 0BD11A0D, Вы писали:

BDA>Не у всех под рукой есть лохи, которые знают C++ и которые с зарплатой, написанием, поддержкой и всем говном дешевле, чем просто еще один сервер в стойку.


Слишком толсто, тренируйся ещё
Matrix has you...
Re[35]: cppcms
От: Evgeny.Panasyuk Россия  
Дата: 25.09.14 12:32
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>Цитирование кода работает во время компиляции.

EP>>А непосредственно разбор деревьев выражений (пусть и сгенерированных в compile-time)?
НС>По желанию. Можно в рантайме, можно специальной тулзой во время компиляции.

Как именно работает такая тулза?

НС>>>И даже заранее скомпилировать запросы часть провайдеров позволяет.

EP>>Вся работа будет выполнена на этапе сборки проекта, до всякого запуска приложения?
НС>Да.

В общих словах, какой конкретно механизм?

EP>> Покажи пример такого провайдера.

НС>bltoolkit.

Насколько я понял из статьи IT, у BLToolkit разбор происходит в runtime, просто отельные части кэшируются. Что, например, видно по отрыву от Native Query, в приведённой им табличке.
Re[36]: cppcms
От: Ночной Смотрящий Россия  
Дата: 25.09.14 13:16
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

НС>>По желанию. Можно в рантайме, можно специальной тулзой во время компиляции.

EP>Как именно работает такая тулза?

Сканирует сборки, находит нужное, генерирует дополнительную сборку, потом использует ее в рантайме.

EP>>> Покажи пример такого провайдера.

НС>>bltoolkit.
EP>Насколько я понял из статьи IT, у BLToolkit разбор происходит в runtime, просто отельные части кэшируются.

Там есть отдельный сторонний проект, его не IT делал. Но популярностью он так чтобы сильно не страдал, потому что сейчас редко кто лазит в БД из клиента напрямую, а на сервере см. ранее.
Re[5]: cppcms
От: 0BD11A0D  
Дата: 25.09.14 13:36
Оценка:
Здравствуйте, Sheridan, Вы писали:

BDA>>Не у всех под рукой есть лохи, которые знают C++ и которые с зарплатой, написанием, поддержкой и всем говном дешевле, чем просто еще один сервер в стойку.


S>Слишком толсто, тренируйся ещё


Толсто, это в смысле я — интернет-провокатор, неудачно провоцирую (я в этой фене не силен)? Так нет же, я на полном серьезе говорю: вы тут какую-то херню обсуждаете, безопасность и прочее, а слона — экономическую нецелесообразность — в упор не видите. И никто не видит. Или видит, но не пишет. Ну ладно, у меня есть время и желание написать, пишу: использовать C++ вообще часто бывает невыгодно, а уж экономить на серверах, привлекая сколько-нибудь квалифицированного сиплюплюсника, это самое тупое, что я за день (нет, за неделю) услышал.

То, что вы пример (? — точно не знаю, но похоже на то) редкого сиплюсплюсника, который стоит дешевле сервера, меня мало интересует. Это проблемы вашего ЧСВ (правильно употребил?).
Re[37]: cppcms
От: Evgeny.Panasyuk Россия  
Дата: 25.09.14 13:54
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>По желанию. Можно в рантайме, можно специальной тулзой во время компиляции.

EP>>Как именно работает такая тулза?
НС>Сканирует сборки, находит нужное, генерирует дополнительную сборку, потом использует ее в рантайме.

Понятно, то есть по всей видимости в самом языке никак
Если же брать внешние тулзы, то в C++ внезапно появляется и compile-time reflection, и полноценное цитирование, и монадический DO-сахар, и т.д. и т.п. А в том же Java, например, структуры и полноценные шаблоны

Кстати, по поводу внешних тулз — есть довольно оригинальный метод подключения их к C++ (видел в какой-то презентации):
template<typename Tree>
void interaction_with_tool();

Смысл в том, что interaction_with_tool не реализован. И если где-то в коде будет вызов interaction_with_tool<SomeExpressionTree>(); — то на стадии линковки вылезет соответствующий unresolved symbol, в котором будет закодирована вся информация о типе SomeExpressionTree (который может представлять древовидное выражение).
Внешняя тулза может найти все такие символы, реализовать (анализируя дерево типа) и выдать соответствующий объектный файл для линковки.
Re[6]: cppcms
От: Хон Гиль Дон Россия  
Дата: 25.09.14 14:15
Оценка: +2
Здравствуйте, 0BD11A0D, Вы писали:


BDA>Толсто, это в смысле я — интернет-провокатор, неудачно провоцирую (я в этой фене не силен)? Так нет же, я на полном серьезе говорю: вы тут какую-то херню обсуждаете, безопасность и прочее, а слона — экономическую нецелесообразность — в упор не видите. И никто не видит. Или видит, но не пишет. Ну ладно, у меня есть время и желание написать, пишу: использовать C++ вообще часто бывает невыгодно, а уж экономить на серверах, привлекая сколько-нибудь квалифицированного сиплюплюсника, это самое тупое, что я за день (нет, за неделю) услышал.


Гуглу и Фейсбуку про это расскажи, ага.

BDA>То, что вы пример (? — точно не знаю, но похоже на то) редкого сиплюсплюсника, который стоит дешевле сервера, меня мало интересует. Это проблемы вашего ЧСВ (правильно употребил?).


Что интересно, если некто развлекается, изготавливая программно-аппаратный комплекс для исполнения "имперского марша" на старых флопповодах и матричных принтерах или склеивая из желудей и спичек макет Тадж-Махала — это нормуль, а если сайт на плюсах ваяет — ужас-ужас, как можно.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[33]: cppcms
От: alex_public  
Дата: 25.09.14 14:39
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

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


Не смеши меня. Никакой jit даже близко не сравним с оптимизатором кода типа современного gcc, icc и т.п.

НС>Какое быстродействие? Компилятор ЯП ничего не знает про SQL или какой то другой EDSL, поэтому от его оптимизаций может произойти что угодно, от замедления до полной невозможности построить запрос.


Оптимизируется уже сгенерированный edsl'е, C++ код, а не сам edsl код. )

НС>Не все, только те которые пытаются натянуть сову на глобус,т.е. пытаются работать с БД как будто это объекты в памяти. Потому что эта абстракция страшно течет.


Ну загрузка/выгрузка объекта в таблицу мне кажется весьма удобной и главное максимально типобезопасной.

_>>Простейший тестовый пример того, о чём я тут сейчас говорил, можно увидеть здесь http://rsdn.ru/forum/philosophy/5369287
Автор: alex_public
Дата: 21.11.13

НС>Не увидел там ничего, что не умеет линк. Более того, конкретно для линка вообще проблемы со чего то там с чем то нет — потому что он умеет анонимные типы, т.е. тип кортежа выводится по месту, прямо в запросе.

Естественно реализовать можно. Вопрос в том какими усилиями. Код на C++ ты видел. Теперь интересно глянуть на объём аналогичного кода при использование "правильного доступа к БД"...
Re[7]: cppcms
От: 0BD11A0D  
Дата: 25.09.14 15:08
Оценка:
Здравствуйте, Хон Гиль Дон, Вы писали:

ХГД>Гуглу и Фейсбуку про это расскажи, ага.


Это называется передергиванием и за это морду бьют на базаре при игре в три листка. Вот что он пишет:

>Профит да, в высоконагруженных. Но не только. Еще есть вариант не тратиться на железо, а запустить на том, что есть


То есть, у него не нагрузка высокая (в отличие от Г и Ф), а просто железо не тянет или тянет плохо. Но вместо апгрейда приходит белый рыцарь, переписывать все на C++.

А вы, спустя два ответа, про это «забываете». И, кстати, насколько я знаю, в Фейсбуке пишут на PHP/Hack. Из новостей первое попавшееся под руку: http://www.fastcolabs.com/3028778/why-facebook-invented-a-new-php-derived-language-called-hack

Короче, с шулерами не играю, зовите следующего.

BDA>>То, что вы пример (? — точно не знаю, но похоже на то) редкого сиплюсплюсника, который стоит дешевле сервера, меня мало интересует. Это проблемы вашего ЧСВ (правильно употребил?).


ХГД>Что интересно, если некто развлекается, изготавливая программно-аппаратный комплекс для исполнения "имперского марша" на старых флопповодах и матричных принтерах или склеивая из желудей и спичек макет Тадж-Махала — это нормуль, а если сайт на плюсах ваяет — ужас-ужас, как можно.


Я б спросил, кто это тут развлекается написанием сайта на плюсах, когда Шеридан это делает за деньги («в перерывах между остальной работой», как он сам пишет), но спрашивать уже желания не осталось.
Re[8]: cppcms
От: Хон Гиль Дон Россия  
Дата: 25.09.14 15:35
Оценка: +1
Здравствуйте, 0BD11A0D, Вы писали:


ХГД>>Гуглу и Фейсбуку про это расскажи, ага.


BDA>Это называется передергиванием и за это морду бьют на базаре при игре в три листка. Вот что он пишет:


>>Профит да, в высоконагруженных. Но не только. Еще есть вариант не тратиться на железо, а запустить на том, что есть


BDA>То есть, у него не нагрузка высокая (в отличие от Г и Ф), а просто железо не тянет или тянет плохо. Но вместо апгрейда приходит белый рыцарь, переписывать все на C++.


BDA>А вы, спустя два ответа, про это «забываете».


А вот ты пишешь — "То, что вы пример (? — точно не знаю, но похоже на то) редкого сиплюсплюсника, который стоит дешевле сервера, меня мало интересует". Т.е., вывод "а уж экономить на серверах, привлекая сколько-нибудь квалифицированного сиплюплюсника, это самое тупое, что я за день (нет, за неделю) услышал" относился не конкретно к Шеридану, который "мало интересует", а вообще. И кто тут передергивает?


BDA> И, кстати, насколько я знаю, в Фейсбуке пишут на PHP/Hack. Из новостей первое попавшееся под руку: http://www.fastcolabs.com/3028778/why-facebook-invented-a-new-php-derived-language-called-hack


Это ты просто не в теме. У них одно с другим срощено при помощи Thrift Им, в отличие от некоторых админов, бабосики считать приходится, и плюсы они пихают только там где выгодно.
Вон либы плюсовые выкладывают



BDA>>>То, что вы пример (? — точно не знаю, но похоже на то) редкого сиплюсплюсника, который стоит дешевле сервера, меня мало интересует. Это проблемы вашего ЧСВ (правильно употребил?).


ХГД>>Что интересно, если некто развлекается, изготавливая программно-аппаратный комплекс для исполнения "имперского марша" на старых флопповодах и матричных принтерах или склеивая из желудей и спичек макет Тадж-Махала — это нормуль, а если сайт на плюсах ваяет — ужас-ужас, как можно.


BDA>Я б спросил, кто это тут развлекается написанием сайта на плюсах, когда Шеридан это делает за деньги («в перерывах между остальной работой», как он сам пишет), но спрашивать уже желания не осталось.


Ну проходи мимо, раз спрашивать не хочешь
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[38]: cppcms
От: Ночной Смотрящий Россия  
Дата: 25.09.14 15:36
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Понятно, то есть по всей видимости в самом языке никак


А зачем это делать в самом языке?

EP>Если же брать внешние тулзы, то в C++ внезапно появляется и compile-time reflection, и полноценное цитирование, и монадический DO-сахар, и т.д. и т.п. А в том же Java, например, структуры и полноценные шаблоны


Есть существенная разница между препроцессорами исходников и генерацией дополнительной dll по бинарнику.
Re[34]: cppcms
От: Ночной Смотрящий Россия  
Дата: 25.09.14 15:36
Оценка:
Здравствуйте, alex_public, Вы писали:

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

_>Не смеши меня. Никакой jit даже близко не сравним с оптимизатором кода типа современного gcc, icc и т.п.

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

НС>>Не все, только те которые пытаются натянуть сову на глобус,т.е. пытаются работать с БД как будто это объекты в памяти. Потому что эта абстракция страшно течет.

_>Ну загрузка/выгрузка объекта в таблицу мне кажется весьма удобной и главное максимально типобезопасной.

Берешь NoSQL в руки и вперед. А РСУБД ты так только раком сможешь поставить.

НС>>Не увидел там ничего, что не умеет линк. Более того, конкретно для линка вообще проблемы со чего то там с чем то нет — потому что он умеет анонимные типы, т.е. тип кортежа выводится по месту, прямо в запросе.

_>Естественно реализовать можно. Вопрос в том какими усилиями.

Никаких усилий не нужно.

_> Код на C++ ты видел.


Так и для того же linq2db код будем примерно таким же.

_> Теперь интересно глянуть на объём аналогичного кода при использование "правильного доступа к БД"...


Person, точно соотвествующий таблице, вообще руками писать не надо, он генерируется автоматично по схеме БД.
А запросы твои — очень просто:
db.CreateTable<Person>();
for(int i=0; i<10; i++)
  db.Persons.Insert(new {ID = i, Name = "name_" + i, Total = Math.Sin(i/3.0)});
// Неправильный вариант, как у тебя
foreach (var person in db.Persons)
    Console.WriteLine("{0} {1} {3} {4}", person.ID, person.Name, person.Total, person.Runtime);
// Правильный вариант
foreach (var person in db.Persons.Select(p => new {p.ID, p.Name, p.Total, p.Runtime}))
    Console.WriteLine("{0} {1} {3} {4}", person.ID, person.Name, person.Total, person.Runtime);


Я до сих пор не понимаю что ты продемонстрировать хочешь.
Re[39]: cppcms
От: Evgeny.Panasyuk Россия  
Дата: 25.09.14 16:01
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

EP>>Понятно, то есть по всей видимости в самом языке никак

НС>А зачем это делать в самом языке?

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

EP>>Если же брать внешние тулзы, то в C++ внезапно появляется и compile-time reflection, и полноценное цитирование, и монадический DO-сахар, и т.д. и т.п. А в том же Java, например, структуры и полноценные шаблоны

НС>Есть существенная разница между препроцессорами исходников и генерацией дополнительной dll по бинарнику.

Конечно есть.
Из того что я привёл один конкретный пример, который использует специфичный подход, никак не следует что для решения подобных задач возможен и используется только он
Например, упомянутый ранее ODB, использует как раз препроцессинг исходников
Re[7]: cppcms
От: genre Россия  
Дата: 25.09.14 16:10
Оценка:
Здравствуйте, Хон Гиль Дон, Вы писали:

ХГД>Гуглу и Фейсбуку про это расскажи, ага.


не надо путать реальный high load с экономией на спичках.

то что тут продемонстрировано делается за 1 день работы + хостинг ценой в доли процента от зарплаты программиста.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[40]: cppcms
От: Ночной Смотрящий Россия  
Дата: 25.09.14 16:15
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


Это все достигается и без такой интеграции.

EP>Например, упомянутый ранее ODB, использует как раз препроцессинг исходников


Вот это и плохо.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.