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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Forward Declaration / Forward Reference, и увеличение скорости скомпиляции... 
V
    Опции темы
SABROG
  Дата 21.4.2009, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Вопрос теоретический. Еще раз напомню особенности для Forward Declaration. Без включения #include можно объявлять ссылки или указатели на объект любого класса таким образом:

Код

#ifndef MYHEADER_H
#define MYHEADER_H

class MyType;

class MyClass
{
public:
    MyClass();
    ~MyClass();

private:
MyType *pointer;
};

#endif // MYHEADER_H


Код


#include "myheader.h"

MyClass::MyClass()
{
    pointer = new MyType;
}

MyClass::~MyClass()
{

}


Я специально убрал #include, где прописан тип MyType, чтобы как-бы повысить скорость компиляци. Но в итоге то .cpp файл не будет компилиться, т.к.  ему все-равно нужно все знать о типе MyType. Вопрос в том, как тогда нужно сделать рефакторинг модулей, чтобы и #include убрать с объявлением типа и при этом не прописывать новый #include в .cpp файле. Я логику подобной оптимизации по скорости компиляции никак не уловлю. Или для такой структуры программы оптимизация не нужна в принципе, т.к. нечего оптимизировать - одно последовательное включение. А если хедер будет использоваться сразу в 10 .cpp файлах, неужели лучше (для скорости компиляции) прописать в каждом из десяти файлов - #include с объявлением MyType, вместо того, чтобы это сделать один раз в общем заголовочном файле?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
zim22
Дата 21.4.2009, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



не хотите все заголовки впихнуть в stdafx.h
установить в опциях компилятора Create/Use Precompiled Header
и потом в .cpp файле в первой строчке кода делать инклуд stdafx.h
?

Это сообщение отредактировал(а) zim22 - 21.4.2009, 19:31


--------------------
PM MAIL   Вверх
SABROG
Дата 21.4.2009, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Я использую gcc. Насчет redunant include guards, precompiled headers, pragma once, multicore compilation и distribute compilation - осведомлен. Меня сейчас интересует именно вопрос с forward declaration.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
mes
Дата 21.4.2009, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(SABROG @  21.4.2009,  18:27 Найти цитируемый пост)
А если хедер будет использоваться сразу в 10 .cpp файлах, неужели лучше (для скорости компиляции) прописать в каждом из десяти файлов - #include с объявлением MyType, вместо того, чтобы это сделать один раз в общем заголовочном файле? 

в этом разницы нет, что он одним файлом все 10 подключит, что по отдельности.
Но что лучше каждому из 10 cpp передавать по 2-3 разных хидера по 5кб или один общий  размером 50  кб ;)










--------------------
PM MAIL WWW   Вверх
SABROG
Дата 21.4.2009, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Цитата(mes @ 21.4.2009,  21:02)
Но что лучше каждому из 10 cpp передавать по 2-3 разных хидера по 5кб или один общий  размером 50  кб ;)

Ну так то вроде бы от перемены мест слагаемых сумма не меняется. А вот что будет быстрее для компилятора - 10 раз прочитать с винчестера 10 5кб-ных файлов или считать 50кб одним махом. Мне почему-то кажется второе. Например, если копировать сотни мелких файлов в винде это долгая операция в отличае от копирования одного файла, скажем .zip архива с нулевой степенью сжатия, где будут находится все эти файлы. Только у меня еще остается вопрос. Если поменять что-то в одном таком общем хедере, то перекомпиляция будет для всех .cpp файлов в которые он включен? А это уже будет обратный эффект тому ради чего создавался этот общий хедер.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
mes
Дата 21.4.2009, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(SABROG @  21.4.2009,  20:53 Найти цитируемый пост)
. А вот что будет быстрее  прочитать с винчестера 10 5кб-ных файлов или считать 50кб одним махом

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

ну а если хотите съэкономить на считывании то добавьте второю пару стражей
Код

//file.h
#ifndef FILE_H_
#define FILE_H_

// file.cpp
#ifndef FILE_H_
#include "file.h"
#endif

 smile 


Это сообщение отредактировал(а) mes - 21.4.2009, 22:05


--------------------
PM MAIL WWW   Вверх
SABROG
Дата 21.4.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Ну со стражами проблем у меня нет. Это наглядный пример redunant include guards (ну или pragma once).
Но, если возвращаться к forward declaration, то как должна выглядеть структура модулей, чтобы это благоприятно сказывалось на скорости компиляции (т.е. если забыть о первичном назначении forward declaration и сосредоточиться на побочном эффекте невключения лишних заголовков)?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
J0ker
Дата 21.4.2009, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



а с какого перепугу скорость компиляции должна увеличиться?



--------------------
user posted image
PM MAIL   Вверх
mes
Дата 21.4.2009, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(SABROG @  21.4.2009,  21:16 Найти цитируемый пост)
Ну со стражами проблем у меня нет. Это наглядный пример redunant include guards (ну или pragma once).

Судя по высказыванию Вы не разобрались с примером. Никто не говорил что у Вас проблемы со стражами.
Просто при обычном(одинарном) использовании страж, вначале считывается файл, потом проверяется включен ли он уже.
А при двойном, как в примере выше, вначале проверяется включен ли уже такой файл и если не включен, то тогда происходит считывание.
Так что эффект от подобного использования есть и в инете я помойму даже видел сравнительную таблицу.

Цитата(SABROG @  21.4.2009,  21:16 Найти цитируемый пост)
Но, если возвращаться к forward declaration, то как должна выглядеть структура модулей,... на побочном эффекте невключения лишних заголовков

Все как и обычно, только в хидеры ничего лишнего не подключать.
ну и так как  создавать объекты "вперед объявленнoго" класса нельзя, то следовательно, для случая
Код

class B {    A m_a; }

придется приглашать указатели и new/delete
Код

class B { A * p_a; ..}
B::B() { p_a = new A; }


Добавлено @ 22:49
Цитата(J0ker @  21.4.2009,  21:35 Найти цитируемый пост)
а с какого перепугу скорость компиляции должна увеличиться?

самое интересное что скорость  увеличивается smile
точнее сказать время компиляции уменьшается smile

Это сообщение отредактировал(а) mes - 21.4.2009, 22:51


--------------------
PM MAIL WWW   Вверх
Alek86
Дата 21.4.2009, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

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



Цитата(mes @  21.4.2009,  22:44 Найти цитируемый пост)
самое интересное что скорость  увеличивается

дык с какого перепугу?
forward declarations нужны для уменьшения связи между модулями
то есть при изменении одного ашника в большом проекте, использущем forward declarations нужно будет перекомпиливать меньше модулей, чем в том же проекте, в котором бездумно понапиханы инклуды

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

Это сообщение отредактировал(а) Alek86 - 21.4.2009, 22:59


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 21.4.2009, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Alek86 @  21.4.2009,  21:58 Найти цитируемый пост)
дык с какого перепугу?

меньше модулей подключено -> меньше считывается+меньше парсится. 

Цитата

My experiment was slightly different.  Instead of testing on an existing co debase, I created a test project of 200 header files, every one of which included all the others, and a single cpp file that includes all headers and an empty main function.  I tested timing by turning on build timing in Visual Studio (Tools -> Options -> Projects -> VC++ Build -> Build Timing), then by right-clicking on the main.cpp file and selecting compile.  My timings were as follows:

    * Nothing - 28 seconds
    * #pragma once - 17 seconds
    * Redundant include guards - < 1 second


http://www.gamearchitect.net/Articles/Expe...thIncludes.html

сам я тоже убедился на личном опыте, у меня в проекте было примерно 100 файлов и после тщательной проверки инклудов со применением forward declaration
время сократилось в  почти два раза, точные значения шас не помню, но примерно вместо  2 минут 20 стал компилится 1 min 20.


Цитата(Alek86 @  21.4.2009,  21:58 Найти цитируемый пост)
то есть при изменении одного ашника в большом проекте,

да от этого выгода намного заметнее (так как чaстичная перекомпиляция намного чаще чем полная smile ) и в принципе основное из за чего я использую. smile



Это сообщение отредактировал(а) mes - 21.4.2009, 23:10


--------------------
PM MAIL WWW   Вверх
Alek86
Дата 21.4.2009, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

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



а, точно, еще парсинг
тогда да, есть выгода
хотя странно, что такая огромная


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 21.4.2009, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Alek86 @  21.4.2009,  22:35 Найти цитируемый пост)
тогда да, есть выгода
хотя странно, что такая огромная


Ну а какой ей быть если вместо n нужных строк приходится компилить k*n строк smile 
все зависит от кол-ва включенного лишнего кода smile

Это сообщение отредактировал(а) mes - 21.4.2009, 23:46


--------------------
PM MAIL WWW   Вверх
SABROG
Дата 22.4.2009, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Цитата(mes @  21.4.2009,  22:44 Найти цитируемый пост)
class B { A * p_a; ..}
B::B() { p_a = new A; }

Если эти 2 строки разделить по модулям .h и .cpp. То ошибка будет при компиляции .cpp файла, т.к. тип A нигде не определен, а следовательно #include с объявлением A таким образом просто переносится из .h файла в .cpp файл(ы). Так ведь? А тогда где выйгрыш?

До:

user posted image

После:

user posted image

P.S.: по UML также как и по C++ у меня 3 с натяжкой smile

Это сообщение отредактировал(а) SABROG - 22.4.2009, 00:04


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
mes
Дата 22.4.2009, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(SABROG @  21.4.2009,  23:03 Найти цитируемый пост)
Если эти 2 строки разделить по модулям .h и .cpp. То ошибка будет при компиляции .cpp файла, т.к. тип A нигде не определен, а следовательно #include с объявлением A таким образом просто переносится из .h файла в .cpp файл(ы). Так ведь? А тогда где выйгрыш?

В нарисованном вами случаем нигде. А теперь представьте для 100 хидеров.
Ведь сппшнику необходимы далеко не все файлы. 
Тогда как первом случае в каждый cpp-шних будут включены в каждый все 100, а во 2м также по 2-4 хидера smile
Чтоб лучше представить, на 2й вашей картинке только две линии  про cpp-юнит оставьте. 

Это сообщение отредактировал(а) mes - 22.4.2009, 00:19


--------------------
PM MAIL WWW   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




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


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

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