Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перенос кода из python в C++. Генераторы. 
:(
    Опции темы
turist
  Дата 6.7.2008, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 13.8.2007
Где: Киев

Репутация: нет
Всего: нет



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

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

Это сообщение отредактировал(а) turist - 6.7.2008, 12:31
PM MAIL WWW ICQ Skype GTalk Jabber MSN   Вверх
Lazin
Дата 6.7.2008, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 2
Всего: 154



Я думаю все не надо переписывать, а только то, что является узким местом... байндинг для С++ кода можно сделать к примеру с помощью boost::python, ну и рекурсия для С++ не является чем-то диким smile
Хотя более естественным для С++ было-бы использование цикла, вместо рекурсии...
PM MAIL Skype GTalk   Вверх
albertn
Дата 6.7.2008, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: 30
Всего: 34



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

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

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

Честно говоря мне непонятно зачем нужно переводить программу из Питона в Си. Не проще ли вызывать питоновские фрагменты из Си?
PM WWW ICQ   Вверх
Void
Дата 6.7.2008, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 10
Всего: 173



Не понимаю, какая может быть связь между рекурсией и языком программирования.
Давайте отделим мух от котлет, а именно хвостовую рекурсию как альтернативу циклу и алгоритмы, рекурсивные по своей природе. Первым вариантом пользуются только в чисто функциональных языках, и ни в Питоне, ни в Си++ никто в здравом смысле применять эту технику не будет. Во втором случае альтернатива рекурсии — ручное управление стеком. (Берём алгоритмы, для которых рекурсия или итерация — это вопрос константы, не влияющей на 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());
        }
    }
}



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
megaflop
Дата 18.7.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 5.5.2005
Где: Санкт-Петербург

Репутация: 1
Всего: 1



PyPy 

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?

PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0996 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.