Nov 02, 2011 06:21
Попробовал вчера новомодную фишку C++0x - лямбда выражения. Результат меня впечатлил (но как-то не так).
Впрочем, по порядку. Есть у меня пул объектов (очень маленький, очень простенький, но требования к скорости там весьма существенные). В нем есть метод forEach:
__forceinline void forEach (void (*_func)(T *)) {
BYTE * p = m_pObjects;
BYTE * pf = m_pFlags;
for (int i = m_dwSize; i > 0; i--, p += S, pf++)
if (!((*pf)&0x80))
_func (reinterpret_cast(p));
}
Есть маленький метод вида:
static __inline void doSomethingCB (SomeObject * p) { p->someVirtualMethod (NULL); }
static void doSomethingWithAll () {
g_pObjectPool->forEach (doSomethingCB);
}
Заменяю содержимое doSomethingWithAll на
g_pObjectPool->forEach ([] (SomeObject * p) { p->someVirtualMethod (NULL); });
правлю объявление forEach
__forceinline void forEach (std::function _func) {
компилю, и, внезапно обнаруживаю, что модуль вырос на два килобайта. Удивляюсь, включаю ассемблерный листинг. Разница в размере листинга - 70К.
Залезаю в код и вижу совсем ужасающую картину. Маленький скромный doSomethingWithAll из ~30 команд увеличился до ~70. В нем образовался не только конструктор std::function, но и EH-frame. Сам по себе std::function - с кучей виртуальных методов. И, как окончательный шедевр победы читабельности над здравым смыслом - лямбда не инлайнится. (и вместо одного единственного vmtcall в теле цикла, я получаю два, плюс вызов функции по указателю).
Я помню, еще в прошлом тысячелетии, аналогичную картину с template. Любое использование шаблонов, приводило к чудовищному раздуванию кода. Прошло какие-то десять лет, и шаблоны не только существенно упрощают жизнь, но и уменьшают и ускоряют код. Возможно, с лямбдой будет аналогично, но, по крайней мере, в VC2010 ее можно использовать только если скорость и размер кода не имеют никакого значения.
Возможно, если заменить std::function каким-нибудь своим велосипедом (без виртуальных методов), все будет симпатичнее. Но дело не только в этом. По понятным причинам, я сейчас регулярно просматриваю вакансии в категории "программист C++", и везде в требованиях стоит STL, а в половине случаев, и Boost. Написание замен стандартных классов, общественное мнение категорически не приветствует. Стоит ли удивляться, что аппаратные требования так растут?