Включенный файл из заголовка / исходного файла - PullRequest
3 голосов
/ 22 октября 2009

В чем разница между включением файла из заголовочного файла или из исходного файла в C ++ в отношении производительности во время компиляции?

Каковы причины для включения файлов в исходный файл, а не в заголовочный файл (кроме случаев, когда это абсолютно необходимо)?

Влияет ли один (заголовок) на время компиляции, а другой (исходный файл) - на время ссылки?

Ответы [ 5 ]

12 голосов
/ 22 октября 2009

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

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

Рекомендуется ограничить количество включаемых заголовков теми, которые требуются для объявления класса. Помимо ограничения включений теми типами, которые используются в классе, вы также можете использовать предварительные объявления вместо включений для типов, используемых только в интерфейсе класса по указателю или по ссылке.

По моему опыту, это влияние на производительность обычно не заметно. Скорее всего, он вступает в игру в очень крупных проектах или широко используемых заголовках.

2 голосов
/ 22 октября 2009

Как писал Адам, включение заголовков в заголовок увеличивает ваши блоки компиляции, что снижает производительность. Но это заметно только в крупных проектах. Это очень важно, например, для заголовков ОС, таких как <windows.h>. Вот почему были скомпилированы заголовки и WIN32_LEAN_AND_MEAN .

Но есть и другая проблема с производительностью сборки, если вы без необходимости включаете заголовки в другой заголовок: вам может потребоваться перестроить больше при изменении заголовка.

рассмотреть следующие вопросы:

// A.h
class A
{
    ...
}

// B.h
#include "A.h"
class B
{
    A *_a;
    ...
}

Если вы измените A.h, среда IDE будет перекомпилировать источники, включающие B.h, даже если они не используют класс A. Но если вы измените B.h на:

// B.h
class A; // forward declaration, declared in "A.h"
class B
{
    A *_a;
    ...
}

В этом больше нет необходимости. Это может иметь заметное значение даже для небольших проектов.

1 голос
/ 22 октября 2009

Люди обычно использовали заголовки только из исходного файла (.cpp / другие расширения), чтобы сократить время компиляции, потому что в противном случае он генерировал каскад заголовков. В настоящее время это больше не проблема, и включение заголовков там, где они действительно необходимы (даже другие заголовки) может избежать необходимости включать много заголовков каждый раз в ваши источники ...

http://www.icce.rug.nl/documents/cplusplus/cplusplus07.html#an973 (для более подробного ответа)

1 голос
/ 22 октября 2009

Как говорит Марк, измерьте это в своей среде. Вообще говоря, если вы включите его в исходный файл, он будет прочитан только там, где он включен и необходим. Если вы включите его в заголовочный файл, и этот заголовочный файл будет добавлен многими другими исходными файлами, время компиляции увеличится. Это также причина, по которой вы должны использовать предварительные объявления в заголовочных файлах везде, где это возможно, вместо того, чтобы включать заголовочный файл класса.

1 голос
/ 22 октября 2009

Для любого вопроса производительности реальный ответ - измерить его самостоятельно - ваша среда будет отличаться от окружения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...