2010-12-08 2 views
6

Общепринято, что производительность статических библиотек больше, чем производительность динамических. Мой вопрос: зависит ли это также от того, как DLL уже загружена в память? Я имею в виду, как только инициализация и все произошло, вызывает ли вызов и выполнение функции больше времени в случае динамических библиотек, чем статические библиотеки?Статическая и динамическая производительность библиотеки

+0

Вы спрашиваете о DLL, но ваши вопросы отмечены `linux`. Как выглядит ваша среда? – Asaph 2010-12-08 06:27:26

+0

Вы в Linux или Windows? Системы с разделяемой библиотекой и независимыми от положения системами очень разные. Windows DLL не являются независимыми по позиции в смысле Linux, хотя их можно переместить – 2010-12-08 06:36:13

ответ

8

Отказ от ответственности: Я кузнечик Linux-fu, поэтому могут быть некоторые неточности здесь и там (или просто повсюду). Но общая идея должна быть относительно правильной. И если это не так, я уверен, что добрые люди SO быстро меня поправят. :-)

О, и ссылки, которые я предоставил, ориентированы на Windows. Я был бы признателен, если бы кто-нибудь мог предоставить правильные ссылки, ориентированные на Linux.

Короткий ответ: Он может. Однако, даже если это так, разница в производительности действительно незначительна.

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

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

С load-time dynamic linking компилятор по-прежнему генерирует код для прямого вызова функции, как если бы она была статически связана. Когда загрузчик процессов загружает DLL, он будет ссылаться на компоновщик времени выполнения, чтобы исправить память процесса, чтобы эти вызовы переходили непосредственно к фактическим реализациям функций. Это должно произойти до того, как будет сделан вызов любой функции из загруженной библиотеки. в Windows это выполняется загрузчиком NT DLL, который вызывает LoadLibrary в DLL во время инициализации процесса. В Linux это делается с помощью компоновщика времени выполнения, ld-linux.so.

С /DELAYLOADнагрузкой время динамического связывания, процесс esentially то же, за исключением того, компилятор генерирует код для вызова небольших заглушек, которые будут проверять, если библиотека загружаются, а если нет, будет вызывать загрузчик NT DLL , Таким образом, DLL будет загружаться по требованию, а загрузчик процесса не должен загружать его во время инициализации процесса. Это приводит к более быстрому времени запуска процесса, но производительность вызова остается неизменной. (Обратите внимание, однако, что задержка нагрузки страдает от других недостатков)

Я не знаю, есть ли соответствующая поддержка Linux, но я был бы удивлен, если этого не произойдет.

С run-time dynamic linking ваш код поддерживает указатели на функции и решает, когда нужно загрузить библиотеку. В Windows он должен использовать LoadLibrary и GetProcAddress, в Linux это dlopen, dlsym и dlclose. В любом случае, последствия для времени запуска процесса такие же, как и для динамической компоновки времени загрузки ; однако разыменование указателя при каждом вызове метода добавляет небольшую незначительную стоимость. (Хотя, если вы знаете, что делаете, вы можете сходить с ума и исправить свою память процесса, чтобы избежать разыменования указателя. Однако попытка сделать это правильно на порядок больше, чем преимущества, которые вы получите для выполнения это.)

3

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

0

Сам машинный код в DLL или статической библиотеке имеет одинаковую производительность. Компилятор может, хотя более агрессивно оптимизировать исполняемый файл со статическими библиотеками, особенно при включении генерации кода времени. Можно подумать об удалении неиспользуемых переменных и дублировании кода и размещении кода рядом друг с другом при совместном использовании (см. PGO).

Когда код распределяются между приложениями, лучше использовать DLL файлов из системы точки зрения производительности, так как общее давление памяти системы меньше (если ОС может отображать вид разделы памяти через процессы, которые для Windows делает).

Смежные вопросы