Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > Перенос кода из python в C++. Генераторы.


Автор: turist 6.7.2008, 12:06
Появилась задачка переделывать большие куски python-кода на C++. Некоторые функции "украшены" yield-ами и являются к тому же рекурсивными, вызывая самих себя в циклах типа "for i in this_func()...". Есть ли у кого-нить выработанные паттерны разворачивания таких функций в более C++-ный вид? Уж больно страшным и монтрообразным это пока что представляется. Может, boost какой-нибудь или другая "silver-bullet"?

Вобщем, товарищи программисты, помогите кто чем сможет.

Автор: Lazin 6.7.2008, 13:34
Я думаю все не надо переписывать, а только то, что является узким местом... байндинг для С++ кода можно сделать к примеру с помощью boost::python, ну и рекурсия для С++ не является чем-то диким smile
Хотя более естественным для С++ было-бы использование цикла, вместо рекурсии...

Автор: albertn 6.7.2008, 13:56
yield-ы в принципе можно перевести различными способами:
1. сделать чтобы функция возвращала не итератор а массив целиком
2. сделать какую-либо внешнюю переменную, в которой бы хранилась информация с какого места нужно продолжать и то делать
3. разобраться в логике и написать полностью самому.

Цитата(Lazin @  6.7.2008,  13:34 Найти цитируемый пост)
рекурсия для С++ не является чем-то диким

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

Честно говоря мне непонятно зачем нужно переводить программу из Питона в Си. Не проще ли вызывать питоновские фрагменты из Си?

Автор: Void 6.7.2008, 16:16
Не понимаю, какая может быть связь между рекурсией и языком программирования.
Давайте отделим мух от котлет, а именно хвостовую рекурсию как альтернативу циклу и алгоритмы, рекурсивные по своей природе. Первым вариантом пользуются только в чисто функциональных языках, и ни в Питоне, ни в Си++ никто в здравом смысле применять эту технику не будет. Во втором случае альтернатива рекурсии — ручное управление стеком. (Берём алгоритмы, для которых рекурсия или итерация — это вопрос константы, не влияющей на O большое. Т.е. не рассматриваем случаи вроде наивного рекурсивного вычисления последовательности Фибоначчи.) Для современных компиляторов это крайне редко даёт ощутимый выигрыш. Для интерпретаторов также имеем сомнительный размен рекурсивного вызова на вызов методов структуры данных (списка, к примеру). И всё это ценой потери читаемости алгоритма: premature optimization и далее по тексту.

Ближе к делу. Лучше всего, конечно, вникнуть в логику и не пытаться скопировать максимально близко к тексту. Генераторы эти, по сути, что делают? Обходят некоторую структуру данных, или может подгружают данные извне, или генерируют некоторую последовательность... Думается, общего метода для переноса генераторов в Си++ нет, точнее, он будет излишне сложным.
Например, можно заменить yield на вызов callback-функции.
Код
def flatten(s):
    for elem in s:
        if isinstance(elem, list):
            for x in flatten(elem):
                yield x
        else:
            yield elem

vs (очень условный код)
Код
void flat_iter(const Node &root, callback_t callback)
{
    for (Node::const_iterator i = root.begin(); i != root.end(); ++i)
    {
        NodeBase *node = *i;
        if (Node *children = dynamic_cast<Node*>(node))
        {
            flat_iter(*children, callback);
        }
        else
        {
            callback(dynamic_cast<Leaf*>(node)->value());
        }
    }
}

Автор: megaflop 18.7.2008, 13:59
http://codespeak.net/pypy/dist/pypy/doc/home.html 

The PyPy project aims at producing a flexible and fast Python implementation. The guiding idea is to translate a Python-level description of the Python language itself to lower level languages. Rumors have it that the secret goal is being faster-than-C which is nonsense, isn't it?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)