Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
Подход родился при решении реальной задачи на работе (и именно поэтому он такой, какой есть, а не проще — потому что в реальной задаче все сильно развесистей и MPL очень помогает с этой развесистостью справиться — у меня в реальном коде условия генерятся через MPL, а не запиываются сразу все целиком, как в статье).
(посмотри там на скрытую секцию про макрос PYTHON_DECL — это, опять же, мой рабочий код с кучей (реально кучей, несколько файлов) метапрограммирования внутри, как на препроцессоре, так и на MPL)
Правда они немного устарели в связи с выходом C++11/C++14 — некоторые техники уже не актуальны в связи с новыми языковыми возможностями. Тем не менее общее понимание они дадут на хорошем уровне.
Здравствуйте, Tilir, Вы писали:
T>>>лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов. EP>>Если наткнулись на баг в Spirit'е (экспоненциальная сложность там где её быть не должно) — то нужно открыть ticket в их trac'е. T>Такого рода "баг" это очень часто "споткнулись на неявном неправильном использовании". Свести к простому примеру? Часто не сводится. Выкладывать полностью? Очень много проприетарного кода который не хочется открывать даже примерно.
По моему опыту часто всё локализуется через банальное "разделяй и властвуй" — причём это относится не только к шаблонному мета-программированию.
И только в редких случаях важны какие-то сайд-эффекты влияния под-частей друг на друга (так что при удалении/выключении одной из них исследуемый эффект пропадает).
T>Вот кстати интересно -- а кто что использует для получения "препроцессированных" исходников после всех шаблонных подстановок?
Что конкретно имеется в виду? Для какой цели?
Если для выявления самой долгой instantiation — то тут нужно не раскрытие, а замеры времени.
Если для тестирования — то здесь нужны unit-test'ы, а не результирующие подстановки.
По большому счёту для макросов (или для кодогенерации) результирующие подстановки полезны потому что манипуляция происходит на уровне конкатенации незаконченных текстовых фрагментов кода (которые могут комбинироваться причудливыми способами), в случае же шаблонов картина принципиально иная.
Если же речь идёт не про результирующие подстановки, а про своего рода backtrace воплощений с промежуточными аргументами — то каждый современный компилятор C++ умеет его выводить (при compile error; которую при необходимости можно спровоцировать вручную).
Если же для оценки оптимальности результирующего кода — то тут естественно нужно смотреть в результирующий ASM.
T>Может уже все давно спасены и я один во мраке?
Для отладки и профилирования шаблонного кода создаются разные утилиты, например: Metashell, Templight. Но я пока обхожусь без их помощи.
Здравствуйте, Tilir, Вы писали:
T>На уровне: "сколько раз раскрылся вот этот вот шаблон и с какими параметрами".
Если речь о GCC, то есть флажок -fdump-class-hierarchy
Например, для файла
#include <iostream>
template<class T> struct F {
static const int value = T::value * F< boost::mpl::int_<T::value-1> >::value;
};
template<> struct F< boost::mpl::int_<0> > {
static const int value = 1;
};
int main() {
std::cout << F<boost::mpl::int_<10>>::value << std::endl;
}
получается вот такой вывод:
> grep '^Class F<' test.cpp.002t.class
Class F<mpl_::int_<0> >
Class F<mpl_::int_<10> >
Class F<mpl_::int_<9> >
Class F<mpl_::int_<8> >
Class F<mpl_::int_<7> >
Class F<mpl_::int_<6> >
Class F<mpl_::int_<5> >
Class F<mpl_::int_<4> >
Class F<mpl_::int_<3> >
Class F<mpl_::int_<2> >
Class F<mpl_::int_<1> >
Здравствуйте, kaa.python, Вы писали:
EP>>Шаблоны используются не только для метапрограммирования. А метапрограммирование возможно и без MPL/Fusion/Hana. EP>>Топик же называется "Метапрограммирование в примерах", а не "MPL/Fusion/Hana в примерах" — поэтому и уточняю. KP>Ты прав, переименовал.
на базе Boost.Fusion — описываем структуры через BOOST_FUSION_DEFINE_STRUCT и автоматом получаем serialize, operator<, operator==, hash_value, и любой другой необходимый обход этих структур. Например понадобилось при реализации паука обходящего P2P сеть Bitcoin, причём когда понадобился текстовый dump сообщений — достаточно было только написать соответствующий код рекурсивного обхода структур.
2. MPL используется внутри Boost.Variant — мне он часто требуется в реальных проектах.
3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.
4. MPL используется внутри Boost.TypeErasure, который помогает делать штуки типа std::function и any_iterator (практичность и полезность которых думаю сомнений не вызывает).
5. Товарищ jazzer подробно описывал
конкретный пример использования MPL и Variant в реальном проекте.
Книжек фокусирующихся на примерах использования MPL и Fusion — я не видел.
Но например по Fusion мне вполне хватило примеров из документации к библиотеке — это библиотека для работы с гетерогенными структурами данных, в том числе позволяющая эмулировать compile-time reflection/introspection/reification. Опять таки, думаю полезность reflection не вызывает никаких сомнений.
EP>>Это считается примером или нет? KP>Этот текст? Думаю, очевидно что нет.
Нет, не текст, а Eigen. Мне в реальном проекте понадобился Eigen, внутри которого много template metaprogramming.
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
ну прямо как будто первый день в С++
берешь буст, и грепаешь там "/mpl/", находишь 2000+ файлов которые используют MPL, читаешь как она используется.
— реальные примеры использования MPL для создания реальных библиотек
Здравствуйте, Abyx, Вы писали:
A>ну прямо как будто первый день в С++
Ты как будто первый раз текст на русском читаешь. Я не хочу читать 2000+ файлов и анализировать их, BOOST мало чем отличается от любой другой бибилиотеки и основная его часть решает проблемы существующие в исключительно в голове авторов. Я же хочу некий труд: заметку, статью, которая покажет на примерах полезные практики и варианты использования. Не зря же в качестве примера я упомянул GoF.
Метапрограммирование вообще и сабжи в частности в основном применяются для производства других библиотек, которые и служат для "была пробелема Ы"решения конкретных прикладных задач, либо в свою очередь, служат основой для опять же библиотек, которые ... =)
Пример — boost.proto\boost.mpl -> boost.simd -> nt2 -> HPC
Здравствуйте, kaa.python, Вы писали:
KP>MPL/Fusion/Hana
в рамках некоторого проекта появились восточные коллеги, которые много рассказывают про SPROUT.
выглядит очень солидно дока, правда, недописана... та и без нее вроде все понятно.
непременно опробую, когда появится подходящая задача.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Tilir, Вы писали:
T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.
Время компиляции — это одна сторона. Boost.Spirit жуткий тормоз в рантайме. Если хоть немного важна скорость парсинга, то лучше сразу смотреть на альтернативы.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Здравствуйте, AndrewJD, Вы писали:
AJD>Время компиляции — это одна сторона. Boost.Spirit жуткий тормоз в рантайме. Если хоть немного важна скорость парсинга, то лучше сразу смотреть на альтернативы.
Эээ что? ) Как раз Boost.Spirit один из самых быстрых парсеров. У него скорее другие проблемы. Ориентация на не особо сложные грамматики и проблематичные ошибки (общая проблема всего метапрограммирования на шаблонах). А уж со скоростью там всё отлично. )
Здравствуйте, Tilir, Вы писали:
T>Здравствуйте, jazzer, Вы писали:
J>>Потому что обычно парсинг — это один файл, который почти не меняется. Ну скомпилируется он один раз долго — ну и хрен бы с ним
T>Если что-то можно унести в один файл и забыть, никакого метапрограммирования там вообще не нужно. MP удобно как раз для мест, где нечто расползлось по всему коду и генерировать это одним файлом сложно или неудобно.
Почему же не нужно? Вот спирит — сплошное МП, но в реальном проекте он используется в одном-двух файлах, когда надо что-то парсить.
Не много же проектов, где парсинг — главная часть приложения.
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек?
Нужны примеры именно с использованием MPL/Fusion/Hana? Или подойдут любые TMP примеры?
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
А нет ли какого-нибудь труда, который бы понятным языком разъяснял что это вообще такое? Я в бусте (в его "языковой", "неприкладной" части, то есть не касающейся фукнций ОС и матана) около половины библиотек вполне понимаю что оно и для чего, но вот есть такие о которых вообще сказать что-то сложно — что оно и зачем, не говоря уже о "как работает".
Из доступных книг — http://theboostcpplibraries.com (но там как раз в основном понятные), книга Полухина (в которой тоже в основном простые библиотеки) и загадочная книжка в двух томах "Introduction to the Boost C++ Libraries", на которую есть единственная ссылка — https://skladchik.com/threads/introduction-to-the-boost-c-libraries-volume-i-foundations.11775
Здравствуйте, kaa.python, Вы писали:
EP>>Нужны примеры именно с использованием MPL/Fusion/Hana? Или подойдут любые TMP примеры? KP>Именно по MPL/Fusion/Hana. В общем случае польза шаблонов и варианты их использования вопросов не вызывают.
Шаблоны используются не только для метапрограммирования. А метапрограммирование возможно и без MPL/Fusion/Hana.
Топик же называется "Метапрограммирование в примерах", а не "MPL/Fusion/Hana в примерах" — поэтому и уточняю.
Например библиотека Eigen — там сплошное метапрограммирование, но MPL/Proto они не использовали по каким-то организационным причинам, о чём и пишут в комментариях:
/** \internal
* \file Meta.h
* This file contains generic metaprogramming classes which are not specifically related to Eigen.
* \note In case you wonder, yes we're aware that Boost already provides all these features,
* we however don't want to add a dependency to Boost.
*/
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
именно MPL, или списки типов и алгоритмы работы с ними в принципе?
ну, например, недавно делал обертку для работы с бд. там параметры упаковывал в подобные списки:
struct Type {
typedef Type ( construct )( optional<int>, uuid_t ); // не знаю, как по другому сообщить компилятору, какие типы принимает конструктор :(
Type ( optional<int>, uuid_t );
};
db::result r = db::query( m_link, "select * from table where field_1 = {0} and field_2 = {1}", value1, value2 );
for ( db::result::const_iterator< Type > it = r.begin( ), end = r.end( ); it != end; ++it ) {
Type record( *it );
// ...
}
без техник, описанных в MPL, работать со списками было бы очень не удобно.
Здравствуйте, kaa.python, Вы писали:
KP> Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
Прочитать книжки — 20% ответа. Остальные 80% — найти задачу, требующую MPL, и решить ее (мне помогло).
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Шаблоны используются не только для метапрограммирования. А метапрограммирование возможно и без MPL/Fusion/Hana. EP>Топик же называется "Метапрограммирование в примерах", а не "MPL/Fusion/Hana в примерах" — поэтому и уточняю.
Ты прав, переименовал.
EP>Это считается примером или нет?
Потенциально, это то, что мне нужно.
Глянул еще раз. Не опознал английские версии когда-то прочитанных книг. Тот же "Шаблоны C++" мне показались более полезными.
Спасибо!
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
Один я вижу противоречие между "а нахрена?" и "было дело, пару раз нашел ей применение"?
Здравствуйте, jazzer, Вы писали:
J>Один я вижу противоречие между "а нахрена?" и "было дело, пару раз нашел ей применение"?
Вообще-то да. Противоречия нет, т.к. пару раз найти применение паре функций из огромной библиотеки как раз и говорит о "а нахрена оно все". Как минимум для меня. Но ведь не зря люди столько написали, может я просто что-то не понимаю
Здравствуйте, kaa.python, Вы писали:
KP>Здравствуйте, jazzer, Вы писали:
J>>Один я вижу противоречие между "а нахрена?" и "было дело, пару раз нашел ей применение"?
KP>Вообще-то да. Противоречия нет, т.к. пару раз найти применение паре функций из огромной библиотеки как раз и говорит о "а нахрена оно все". Как минимум для меня. Но ведь не зря люди столько написали, может я просто что-то не понимаю
Очевидно, зависит от задач. У тебя задачи вот такие, что MPL в полный рост не понадобился.
Мне вот бесселевы функции ни разу не понадобились, и чего теперь Есть же люди, которые считают тяжелую математику, им оно нужно. То же с MPL — когда ты пишешь шаблонную библиотеку, которая должна работать с кучей разных типов разных свойств — тебе неизбежно понадобятся какие-то средства, чтоб со всем этим управляться. А если не пишешь — то тебе оно и не надо
Сначала подумал что ты про SAP Hana, вот это, думаю, вопросы пошли в С++ разделе.
KP>"была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили"
я как-то раз применил, так код этот наверняка до сих пор живет без изменений из версии в версию, так как никто его не может изменить кроме меня (:
Здравствуйте, kaa.python, Вы писали:
KP>Я не хочу читать 2000+ файлов и анализировать их, [...] Я же хочу некий труд: заметку, статью, которая покажет на примерах полезные практики и варианты использования.
то есть сам ты трудиться не хочешь, а хочешь чтобы кто-то потрудился за тебя. понятно.
Здравствуйте, kaa.python, Вы писали:
KP>"была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили"
Попробую свой пример изложить. Есть стандарт SVG.
В SVG много элементов, у каждого элемента свой набор атрибутов (пересекающийся с другими эл-тами). У каждого атрибута есть тип.
Эту часть спецификации можно реализовать рантайм возможностями языка (виртуальные ф-ции или свичи) или в compile-time, тогда то и начинается метапрограммирование и, местами, MPL. Кстати, эл-тами MPL контейнеров у меня всегда были не "настоящие" типы, а тэги (пустые классы), возможно это характерно для MPL.
Программист должен иметь возможность выбрать, какие элементы и атрибуты SVG обрабатывать. Это опять же можно сделать в рантайме, но тогда нет compile-time проверки, что программист готов принять данные, которые он выбрал для обработки — только рантайм ассерты. Или же предлагаем ему передать MPL контейнер с тэгами эл-тов и атрибутов, которые он хочет обрабатывать. В последнем случае получаем zero overhead, "not pay for what you don't use" и код пользователя, соответствующий заказанным фичам. И никакого неиспользуемого кода в бинарниках.
Вобщем, если спецификация SVG понятна, можете прикинуть архитектуру такой библиотечки и там автоматически должен возникнуть MPL.
Здравствуйте, kaa.python, Вы писали:
KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы
в этом качестве использовал MPL не раз! возможность не допускать недопустимое использование библиотеки/класса на этапе компиляции бесценна!
MPL вообще часто нужен^W незаменим там, где есть необходимость что-то сделать для множества типов (масло маслянное %) ... сообщений, например, или типов которыми можно (разрешено) инстанциировать что-то (т.е. всеми остальными нельзя). или вот доводилось делать вектор MPLных пар, в котором first это compile time predicate для типа, а second это функтор, который умеет "обрабатывать" данный тип.
до появления variadic templates boost::fusion выручал когда нужно было в зависимости от параметров шаблона генерить в классе методы с непонятным (до компиляции) числом параметров и хранить их до момента вызова или "постепенно" (по очереди) отдавать во внутренние функции вызываемые из "главной"...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.
Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.
Так что для масштабируемости лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.
Что относится и ко всему прочему MP. Оно должно быть маленьким и очень локальным, если вы не хотите собирать свой проект годами.
Здравствуйте, Tilir, Вы писали:
T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.
Вообще странно — у них что, парсинг прям везде?
Потому что обычно парсинг — это один файл, который почти не меняется. Ну скомпилируется он один раз долго — ну и хрен бы с ним
Работа основная (и перекомпиляция) в других файлах идет, не в парсилке же (я надеюсь).
Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).
Здравствуйте, Tilir, Вы писали:
T>Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.
T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.
T>Так что для масштабируемости лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.
T>Что относится и ко всему прочему MP. Оно должно быть маленьким и очень локальным, если вы не хотите собирать свой проект годами.
Здравствуйте, Tilir, Вы писали:
EP>>3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю. T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны.
Что значит "потому что шаблоны"? Шаблоны сами по себе не увеличивают время компиляции экспоненциально. Экспоненциальная сложность может быть у конкретной метапрограммы, но не у шаблонов в общем.
По поводу Spirit — да, компилируется медленно, PCH / Unity Builds помогают только отчасти.
Но я видел в открытых проектах грамматики, которые больше моих на порядки. Если бы рост действительно был бы экспоненциальным — то компиляция занимала бы какое-то нереальное время.
T>У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст. T>Так что для масштабируемости
Я использовал Spirit для небольших грамматик, которые даже в самой пессимистичной перспективе не могли вырасти до больших размеров — вполне себе пример для сабж.
T>лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.
Если наткнулись на баг в Spirit'е (экспоненциальная сложность там где её быть не должно) — то нужно открыть ticket в их trac'е.
T>Что относится и ко всему прочему MP. Оно должно быть маленьким и очень локальным, если вы не хотите собирать свой проект годами.
Оно может быть большим и глобальным, и при этом проект будет собираться быстро. Оно также может быть "маленьким и очень локальным" — но проект будет собираться годами
Здравствуйте, swingus, Вы писали:
S>Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).
Насколько я знаю, у VS до сих пор 32-битный компилятор C++. Тем не менее, добавленная память может использоваться например под дисковый кэш.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
T>>лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.
EP>Если наткнулись на баг в Spirit'е (экспоненциальная сложность там где её быть не должно) — то нужно открыть ticket в их trac'е.
Такого рода "баг" это очень часто "споткнулись на неявном неправильном использовании". Свести к простому примеру? Часто не сводится. Выкладывать полностью? Очень много проприетарного кода который не хочется открывать даже примерно.
И, кстати, локализация "где именно взорвались" для шаблонов это праздник. Потому что раскрывалки шаблонов (аналог -E для макросов) не существует, насколько мне известно. Я в таких случаях смотрю гимпл (это такой IR в GCC) и даю ценные советы на уровне "ну вот тут же у вас 100500 экземпляров создалось" после чего люди действительно могут (иногда и очень примерно) найти у себя проблему.
Вот кстати интересно -- а кто что использует для получения "препроцессированных" исходников после всех шаблонных подстановок? Может уже все давно спасены и я один во мраке?
Там у виндов ограничение на кол-во памяти. Кроме какой-то серверной версии и ключей запуска, все они юзают максимум 4GB.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, swingus, Вы писали:
S>>Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).
EP>Насколько я знаю, у VS до сих пор 32-битный компилятор C++. Тем не менее, добавленная память может использоваться например под дисковый кэш.
Здравствуйте, swingus, Вы писали:
S>>>Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++). EP>>Насколько я знаю, у VS до сих пор 32-битный компилятор C++. Тем не менее, добавленная память может использоваться например под дисковый кэш. S>Там у виндов ограничение на кол-во памяти. Кроме какой-то серверной версии и ключей запуска, все они юзают максимум 4GB.
Ты о чём? Если бы компилятор (cl.exe) был x64 — то он мог бы спокойно использовать больше 4GiB.
4GiB это ограничение для x32 процессов в x64 Windows.
Здравствуйте, jazzer, Вы писали:
J>Потому что обычно парсинг — это один файл, который почти не меняется. Ну скомпилируется он один раз долго — ну и хрен бы с ним
Если что-то можно унести в один файл и забыть, никакого метапрограммирования там вообще не нужно. MP удобно как раз для мест, где нечто расползлось по всему коду и генерировать это одним файлом сложно или неудобно.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>По моему опыту часто всё локализуется через банальное "разделяй и властвуй" — причём это относится не только к шаблонному мета-программированию. EP>И только в редких случаях важны какие-то сайд-эффекты влияния под-частей друг на друга (так что при удалении/выключении одной из них исследуемый эффект пропадает).
Комбинаторные взрывы при MP по моему опыту не локализуются: вы что-то убираете у вас все хорошо, добавляете снова у вас все плохо. Это что-то само является какой-то мрачной запутанной фигней из сторонней библиотеки вроде boost::spirit и отлично работает если вы его вставляете в hello world. "Ну и всё, приехали".
EP>Что конкретно имеется в виду? Для какой цели?
Посмотреть на плюсовый код после всех шаблонных подстановок. На уровне: "сколько раз раскрылся вот этот вот шаблон и с какими параметрами".
Цели в основном: оценка оверхеда по размеру кода, поиск узких мест по времени компиляции.
EP>Если же для оценки оптимальности результирующего кода — то тут естественно нужно смотреть в результирующий ASM.
Ассемблер после оптимизирующего компилятора с LTO это мелко рубленная каша, лучше уж IR на начальных фазах.
T>>Может уже все давно спасены и я один во мраке?
EP>Для отладки и профилирования шаблонного кода создаются разные утилиты, например: Metashell, Templight. Но я пока обхожусь без их помощи.
Здравствуйте, Tilir, Вы писали:
EP>>Что конкретно имеется в виду? Для какой цели? T>Посмотреть на плюсовый код после всех шаблонных подстановок. На уровне: "сколько раз раскрылся вот этот вот шаблон и с какими параметрами".
Достаточно спровоцировать warning внутри шаблона — и компилятор выдаст backtrace воплощений шаблонов, со всеми аргументами. Правда нужно учитывать что воплощения могут мемоизироваться, и повторного вывода не будет.
T>Цели в основном: оценка оверхеда по размеру кода,
По-хорошему нужно смотреть на конечный размер после линковки, так как в объектных файлах может быть много функций которые по факту заинлайнены и больше нигде не требуются. Либо же смотреть размер отдельных конкретных функций.
T>поиск узких мест по времени компиляции.
Само по себе раскрытие здесь не сильно поможет. Нужно либо делать ручное "разделяй и властвуй", либо делать профилирование а-ля Templight.
EP>>Если же для оценки оптимальности результирующего кода — то тут естественно нужно смотреть в результирующий ASM. T>Ассемблер после оптимизирующего компилятора с LTO это мелко рубленная каша, лучше уж IR на начальных фазах.
Если на начальных фазах — то значит не все оптимизации применены, для оценки оптимальности это как-то не айс. А при просмотре ASM обычно есть представление о том что там примерно должно быть, или хотя бы о том чего там быть точно не должно.