Компилятор решает, когда встроить мои функции (в C++)?

При использовании Быть в спящем режиме реализации JPA я нашел, что просто объявление типа как ArrayList вместо Списка позволяет, в спящем режиме для хранения списка данных.

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

@Entity
public class Command implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    ArrayList<String> arguments = new ArrayList<String>();


}
9
задан jkeys 30 July 2009 в 07:28
поделиться

9 ответов

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

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

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

10
ответ дан 4 December 2019 в 06:11
поделиться

Да, окончательное решение о том, встраивать ли ваш код или нет, принимает компилятор C ++. Ключевое слово inline - это предложение, а не требование.

Вот некоторые подробности того, как это решение обрабатывается в компиляторе Microsoft C ++

15
ответ дан 4 December 2019 в 06:11
поделиться

Как многие уже писали, окончательное решение всегда остается за компилятором, даже если вы можете дать четкие подсказки, такие как forceinline.
Частично это объясняется тем, что встраивание не является автоматическим переключением «быстрее». Слишком много встраивания может сделать ваш код намного больше и может помешать другим оптимизациям. См. C ++ FAQ Lite о встроенных функциях и производительности .

4
ответ дан 4 December 2019 в 06:11
поделиться

Да, окончательное решение принимает компилятор. В VS вы можете даже встраивать рекурсивные функции на заданную глубину ;)

#pragma inline_depth( [0... 255] )
3
ответ дан 4 December 2019 в 06:11
поделиться

Насколько мне известно, компилятор автоматически сделает функцию, которую вы объявили встроенной (или написали внутри объявления класса), не встроенной, если он обнаружит цикл, например for, while и т. Д. Это один из примеров, когда последнее слово во встроенных функциях остается за компилятором.

1
ответ дан 4 December 2019 в 06:11
поделиться

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

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

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

1
ответ дан 4 December 2019 в 06:11
поделиться

Просто чтобы добавить свои 5 центов ...

Я нашел эту Гуру недели статью о встраивании очень полезной.

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

С уважением,
Ованес

3
ответ дан 4 December 2019 в 06:11
поделиться

Как и другие отметили, ключевое слово inline - это просто предложение компилятору встроить код. Поскольку компилятор обычно встраивает код, который не был помечен inline , а не встроенный код, который имеет, ключевое слово кажется таким же избыточным, как register или (pre-C ++ 0x) auto .

Однако есть еще одна вещь, на которую влияет ключевое слово inline : оно изменяет связь функции с external (по умолчанию для функций) на встроенный . Встроенная компоновка позволяет каждой единице компиляции содержать свою собственную копию объектного кода, а компоновщик удаляет избыточные копии из конечного исполняемого файла. Если это напоминает вам шаблоны, да, шаблоны также используют встроенную связь.

Поскольку компилятор обычно встраивает код, который не был помечен inline , а не встроенный код, который имеет, ключевое слово кажется таким же избыточным, как register или (pre-C ++ 0x) auto .

Однако есть еще одна вещь, на которую влияет ключевое слово inline : оно изменяет связь функции с external (по умолчанию для функций) на встроенный . Встроенная компоновка позволяет каждой единице компиляции содержать свою собственную копию объектного кода, а компоновщик удаляет избыточные копии из конечного исполняемого файла. Если это напоминает вам шаблоны, да, шаблоны также используют встроенную связь.

Поскольку компилятор обычно встраивает код, который не был помечен inline , а не встроенный код, который имеет, ключевое слово кажется таким же избыточным, как register или (pre-C ++ 0x) auto .

Однако есть еще одна вещь, на которую влияет ключевое слово inline : оно изменяет связь функции с external (по умолчанию для функций) на встроенный . Встроенная компоновка позволяет каждой единице компиляции содержать свою собственную копию объектного кода, а компоновщик удаляет избыточные копии из конечного исполняемого файла. Если это напоминает вам шаблоны, да, шаблоны также используют встроенную связь.

ключевое слово кажется таким же избыточным, как register или (pre-C ++ 0x) auto .

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

ключевое слово кажется таким же избыточным, как register или (pre-C ++ 0x) auto .

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

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

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

4
ответ дан 4 December 2019 в 06:11
поделиться

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

void Foo::bar() { std::cout << "baz"; }

Будет компилятор встроил это под покровы?

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

2
ответ дан 4 December 2019 в 06:11
поделиться
Другие вопросы по тегам:

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