![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Вопрос теоретический. Еще раз напомню особенности для Forward Declaration. Без включения #include можно объявлять ссылки или указатели на объект любого класса таким образом:
Я специально убрал #include, где прописан тип MyType, чтобы как-бы повысить скорость компиляци. Но в итоге то .cpp файл не будет компилиться, т.к. ему все-равно нужно все знать о типе MyType. Вопрос в том, как тогда нужно сделать рефакторинг модулей, чтобы и #include убрать с объявлением типа и при этом не прописывать новый #include в .cpp файле. Я логику подобной оптимизации по скорости компиляции никак не уловлю. Или для такой структуры программы оптимизация не нужна в принципе, т.к. нечего оптимизировать - одно последовательное включение. А если хедер будет использоваться сразу в 10 .cpp файлах, неужели лучше (для скорости компиляции) прописать в каждом из десяти файлов - #include с объявлением MyType, вместо того, чтобы это сделать один раз в общем заголовочном файле? |
||||
|
|||||
zim22 |
|
|||
![]() depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 24 Всего: 69 |
не хотите все заголовки впихнуть в stdafx.h
установить в опциях компилятора Create/Use Precompiled Header и потом в .cpp файле в первой строчке кода делать инклуд stdafx.h ? Это сообщение отредактировал(а) zim22 - 21.4.2009, 19:31 |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Я использую gcc. Насчет redunant include guards, precompiled headers, pragma once, multicore compilation и distribute compilation - осведомлен. Меня сейчас интересует именно вопрос с forward declaration.
|
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
в этом разницы нет, что он одним файлом все 10 подключит, что по отдельности. Но что лучше каждому из 10 cpp передавать по 2-3 разных хидера по 5кб или один общий размером 50 кб ;) |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Ну так то вроде бы от перемены мест слагаемых сумма не меняется. А вот что будет быстрее для компилятора - 10 раз прочитать с винчестера 10 5кб-ных файлов или считать 50кб одним махом. Мне почему-то кажется второе. Например, если копировать сотни мелких файлов в винде это долгая операция в отличае от копирования одного файла, скажем .zip архива с нулевой степенью сжатия, где будут находится все эти файлы. Только у меня еще остается вопрос. Если поменять что-то в одном таком общем хедере, то перекомпиляция будет для всех .cpp файлов в которые он включен? А это уже будет обратный эффект тому ради чего создавался этот общий хедер. |
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Как понял Вы думаете, что если хидеры включены в хидере, а не в .сpp они один раз за всю компиляцию считываютаются. неа.. точно также заново для каждой единицы трансляции (при оговоренном Вами выше условии, об отстствии прекомпиляции) к тому же если тянут лишние хидеры, то в сумме получается выше и по кол-ву считываемыех файлов и по объему текста для парсера. ну а если хотите съэкономить на считывании то добавьте второю пару стражей
![]() Это сообщение отредактировал(а) mes - 21.4.2009, 22:05 |
||||
|
|||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Ну со стражами проблем у меня нет. Это наглядный пример redunant include guards (ну или pragma once).
Но, если возвращаться к forward declaration, то как должна выглядеть структура модулей, чтобы это благоприятно сказывалось на скорости компиляции (т.е. если забыть о первичном назначении forward declaration и сосредоточиться на побочном эффекте невключения лишних заголовков)? |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
а с какого перепугу скорость компиляции должна увеличиться?
|
|||
|
||||
mes |
|
||||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Судя по высказыванию Вы не разобрались с примером. Никто не говорил что у Вас проблемы со стражами. Просто при обычном(одинарном) использовании страж, вначале считывается файл, потом проверяется включен ли он уже. А при двойном, как в примере выше, вначале проверяется включен ли уже такой файл и если не включен, то тогда происходит считывание. Так что эффект от подобного использования есть и в инете я помойму даже видел сравнительную таблицу.
Все как и обычно, только в хидеры ничего лишнего не подключать. ну и так как создавать объекты "вперед объявленнoго" класса нельзя, то следовательно, для случая
придется приглашать указатели и new/delete
Добавлено @ 22:49 самое интересное что скорость увеличивается ![]() точнее сказать время компиляции уменьшается ![]() Это сообщение отредактировал(а) mes - 21.4.2009, 22:51 |
||||||||
|
|||||||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
дык с какого перепугу? forward declarations нужны для уменьшения связи между модулями то есть при изменении одного ашника в большом проекте, использущем forward declarations нужно будет перекомпиливать меньше модулей, чем в том же проекте, в котором бездумно понапиханы инклуды для увеличения скорости компиляции используются precompiled headers как они помогают увеличивать скорость, я не очень понимаю наверное компилер при создании прекомпилед pdb файла приводит их в какой-то полускомпиленный (для шаблонов) вид, который помогает ускорять инстанцирование Это сообщение отредактировал(а) Alek86 - 21.4.2009, 22:59 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
меньше модулей подключено -> меньше считывается+меньше парсится.
http://www.gamearchitect.net/Articles/Expe...thIncludes.html сам я тоже убедился на личном опыте, у меня в проекте было примерно 100 файлов и после тщательной проверки инклудов со применением forward declaration время сократилось в почти два раза, точные значения шас не помню, но примерно вместо 2 минут 20 стал компилится 1 min 20. да от этого выгода намного заметнее (так как чaстичная перекомпиляция намного чаще чем полная ![]() ![]() Это сообщение отредактировал(а) mes - 21.4.2009, 23:10 |
|||
|
||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
а, точно, еще парсинг
тогда да, есть выгода хотя странно, что такая огромная |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Ну а какой ей быть если вместо n нужных строк приходится компилить k*n строк ![]() все зависит от кол-ва включенного лишнего кода ![]() Это сообщение отредактировал(а) mes - 21.4.2009, 23:46 |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Если эти 2 строки разделить по модулям .h и .cpp. То ошибка будет при компиляции .cpp файла, т.к. тип A нигде не определен, а следовательно #include с объявлением A таким образом просто переносится из .h файла в .cpp файл(ы). Так ведь? А тогда где выйгрыш? До: ![]() После: ![]() P.S.: по UML также как и по C++ у меня 3 с натяжкой ![]() Это сообщение отредактировал(а) SABROG - 22.4.2009, 00:04 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
В нарисованном вами случаем нигде. А теперь представьте для 100 хидеров. Ведь сппшнику необходимы далеко не все файлы. Тогда как первом случае в каждый cpp-шних будут включены в каждый все 100, а во 2м также по 2-4 хидера ![]() Чтоб лучше представить, на 2й вашей картинке только две линии про cpp-юнит оставьте. Это сообщение отредактировал(а) mes - 22.4.2009, 00:19 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |