Какие методы могут использоваться для ускорения времени компиляции C++?

Неустранимая ошибка: использование $ this, если не в контексте объекта

$this - специальная переменная в PHP , которая не может быть назначена. Если он доступен в контексте, где он не существует, эта фатальная ошибка указывается.

Эта ошибка может возникнуть:

  1. Если нестатический метод называется статически , Пример:
    class Foo {
       protected $var;
       public function __construct($var) {
           $this->var = $var;
       }
    
       public static function bar () {
           // ^^^^^^
           echo $this->var;
           //   ^^^^^
       }
    }
    
    Foo::bar();
    
    Как исправить: снова просмотрите свой код, $this может использоваться только в контексте объекта и никогда не должен использоваться в статическом методе. Кроме того, статический метод не должен обращаться к нестатистическому свойству. Используйте self::$static_property для доступа к статическому свойству.
  2. Если код из метода класса был скопирован в нормальную функцию или только глобальную область и , сохраняя специальную функцию $this переменная. Как исправить: Просмотрите код и замените $this на другую переменную замещения.

Вопросы, относящиеся:

  1. Вызов нестатический метод как статический: PHP Неустранимая ошибка: использование $ this, если не в объектном контексте
  2. Копировать код: Неустранимая ошибка: использование $ this, если не в объекте context
  3. Все «Использование $ this, если не в контексте объекта» Вопросы по Stackoverflow

239
задан Community 23 May 2017 в 02:34
поделиться

18 ответов

Методы языка

Идиома Pimpl

Смотрит на идиома Pimpl здесь , и здесь , также известный как непрозрачный указатель или обрабатывает классы. Мало того, что это ускоряет компиляцию, это также увеличивает безопасность исключения, когда объединено с подкачка неброска функция. Идиома Pimpl позволяет Вам уменьшить зависимости между заголовками и уменьшает объем перекомпиляции, которая должна быть сделана.

Предописания

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

ввод-вывод потоки особенно известны замедлением сборок. При необходимости в них в заголовочном файле попробуйте #including <iosfwd> вместо <iostream> и #include <iostream> заголовок в файле реализации только. <iosfwd> заголовок содержит предописания только. К сожалению, другие стандартные заголовки не имеют соответствующего заголовка объявлений.

Предпочитают pass-by-reference передачу значением в функциональных подписях. Это избавит от необходимости к #include соответствующие определения типа в заголовочном файле, и необходимо будет только передать - объявляют тип. Конечно, предпочтите, чтобы ссылки константы на ссылки неконстанты избежали неясных ошибок, но это - проблема для другого вопроса.

Условия охраны

защитные условия Использования помешать заголовочным файлам включаться несколько раз в единственную единицу перевода.

#pragma once
#ifndef filename_h
#define filename_h

// Header declarations / definitions

#endif

И при помощи прагмы и при помощи ifndef, Вы получаете мобильность простого макро-решения, а также оптимизацию скорости компиляции, которую некоторые компиляторы могут сделать в присутствии pragma once директива.

Уменьшают взаимозависимость

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

Параметры компилятора

Предварительно скомпилированные Заголовки

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

Быть осторожными, что Вы только включаете редко изменяемый материал в предварительно скомпилированные заголовки, или Вы могли закончить тем, что делали полный, восстанавливает чаще, чем необходимый. Это - хорошее место для [1 118] STL , заголовки и другая библиотека включают файлы.

кэш является другой утилитой, которая использует в своих интересах кэширующиеся методы для ускорения вещей.

Параллелизм Использования

Много компиляторов / поддержка IDE с помощью нескольких ядер/Центральных процессоров, чтобы сделать компиляцию одновременно. В [1 120] GNU Делает (обычно используемый с GCC), использует -j [N] опция. В Visual Studio существует опция под предпочтениями, чтобы позволить ему разрабатывать несколько проектов параллельно. Можно также использовать /MP опция для параллелизма уровня файла вместо просто параллелизма уровня проекта.

Другие параллельные утилиты:

Более низкий Уровень

Оптимизации, Чем больше компилятор пытается оптимизировать, тем тяжелее это должно работать.

Общие Библиотеки

Перемещение Вашего менее часто изменяемого кода в библиотеки может уменьшить время компиляции. При помощи общих библиотек (.so или .dll), можно уменьшить соединение времени также.

Получают Более быстрый Компьютер

[еще 1154] RAM, более быстрые жесткие диски (включая SSD), и больше центральных процессоров/ядер будет все иметь значение в скорости компиляции.

250
ответ дан 17 revs, 5 users 61% 23 November 2019 в 03:21
поделиться

Если у Вас есть многоядерный процессор, и Visual Studio (2005 и позже), а также многопроцессорные компиляции поддержки GCC. Это - что-то, чтобы включить, если у Вас есть аппаратные средства, наверняка.

2
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

Динамическое подключение (.so) может быть намного намного быстрее, чем статическое подключение (.a). Особенно, когда у Вас есть медленный сетевой диск. Это - так как у Вас есть весь код в.a файле, который должен быть обработан и выписан. Кроме того, намного больший исполняемый файл должен быть выписан к диску.

3
ответ дан 23 November 2019 в 03:21
поделиться

Где Вы проводите свое время? Действительно ли Вы являетесь зависящими от ЦП? Память связывается? Диск связывается? Можно ли использовать больше ядер? Больше RAM? Вам нужен RAID? Вы просто хотите повысить эффективность своей существующей системы?

.

Под gcc/g ++, Вы посмотрели кэш ? Может быть полезно при выполнении make_clean _; _ делают много.

3
ответ дан phuclv 23 November 2019 в 03:21
поделиться
  • Обновление Ваш компьютер

    1. Получает четырехъядерное (или двойная квадратическая система)
    2. Получают много RAM.
    3. Использование Электронный диск, чтобы решительно уменьшить задержки файлового ввода-вывода. (Существуют компании, которые делают IDE и Электронные диски SATA, которые действуют как жесткие диски).
  • Тогда у Вас есть все свои другие типичные предложения

    1. , Использование предварительно скомпилировало заголовки при наличии.
    2. Уменьшают объем связи между частями Вашего проекта. Изменение одного заголовочного файла обычно не должно требовать перекомпиляции Вашего всего проекта.
4
ответ дан Uhall 23 November 2019 в 03:21
поделиться

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

Рекурсивный Read Делают Продуманными Вредный (PDF) для обсуждения этой темы в средах Unix.

5
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

Используйте

#pragma once

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

5
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

Больше RAM.

Кто-то говорил об Электронных дисках в другом ответе. Я сделал это с 80286 и , Turbo C++ (выставочный возраст) и результаты был феноменален. Как была потеря данных когда разрушенная машина.

8
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

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

, Например:

// T.h
class Class2; // Forward declaration

class T {
public:
    void doSomething(Class2 &c2);
private:
    Class2 *m_Class2Ptr;
};

// T.cpp
#include "Class2.h"
void Class2::doSomething(Class2 &c2) {
    // Whatever you want here
}

Меньше включают средства намного меньше работы для препроцессора, если Вы делаете это достаточно.

6
ответ дан Evan Teran 23 November 2019 в 03:21
поделиться

Когда я вышел из колледжа, первый реальный достойный производства код C++, который я видел, имел эти тайные #ifndef... Директивы #endif, промежуточные их, где заголовки были определены. Я спросил парня, который писал код об этих всеобъемлющих вещах очень наивным способом и был представлен миру крупномасштабного программирования.

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

9
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

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

первый, distcc, выполняет шаг препроцессора локально и затем отправляет вывод в первый доступный компилятор в сети. Это требует того же компилятора и версий библиотеки во всех настроенных узлах в сети.

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

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

11
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

Вот некоторые:

  • Использование все ядра процессора путем запуска задания нескольких-компиляций (make -j2 хороший пример).
  • Выключают или понижают оптимизацию (например, GCC намного быстрее с -O1, чем -O2 или -O3).
  • Использование предварительно скомпилированные заголовки .
11
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

Я просто свяжусь со своим другим ответом: , Как ВЫ уменьшаете время компиляции и соединение времени для проектов Visual C++ (собственный C++)? . Другая точка, которую я хочу добавить, но которая часто вызывает проблемы, должна использовать предварительно скомпилированные заголовки. Но, только используйте их для частей, которые почти никогда не изменяются (как заголовки инструментария GUI). Иначе они будут стоить Вам большего количества времени, чем они сохраняют Вас в конце.

Другая опция, когда Вы работаете с GNU, делают, для включения -j<N> опция:

  -j [N], --jobs[=N]          Allow N jobs at once; infinite jobs with no arg.

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

, Но компоновщик самостоятельно может быть поточным, и это - то, что GNU gold делает компоновщик ELF . Это оптимизировано поточный код C++, который, как говорят, связывает объектные файлы ELF величина быстрее, чем старое ld (и был на самом деле включен в binutils).

15
ответ дан Community 23 November 2019 в 03:21
поделиться

Существует вся книга по этой теме, которая названа Крупномасштабная Разработка программного обеспечения C++ (записанный John Lakos).

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

15
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

Я рекомендовал бы эти статьи от "Игр из, Инди-Игровой дизайн И Программирование":

Предоставленный, они довольно стары - необходимо будет повторно протестировать все с последними версиями (или версии, доступные Вам), для получения реалистических результатов. Так или иначе это - хороший источник для идей.

32
ответ дан Paulius 23 November 2019 в 03:21
поделиться

Вы могли использовать Сборки Единицы .

†"вЂ"

6
ответ дан Peter Mortensen 23 November 2019 в 03:21
поделиться

В Linux (и, возможно, некоторых других * NIX) вы можете действительно ускорить компиляцию, НЕ СМОТРЕТЬ на вывод и переключившись на другой TTY.

Вот это эксперимент: printf замедляет мою программу

2
ответ дан 23 November 2019 в 03:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: