Dynamic (shared) vs. Static Library Performance

Dec 11, 2018 · 4 min read
Trinity College — Dublin, Ireland

Table of Contents:

  • What is a shared library?
  • How to create a shared library?
  • Why are they useful?
  • How is it different than a static library?

So what are they?

A shared library is a library that dynamically links during compilation when a user compiles a .c file. Static and dynamic linking are two processes of collecting and combining multiple object files in order to create a single executable file. The main difference between the two is the type of linking they do when creating an executable file.

Contrary to a static library, a dynamic library performs the linking process as a program is executed in Linux. Moreover, dynamic libraries are loaded into memory by programs when they are executed. During compilation, a shared libraries machine code is cached locally and has a version control of sorts that keeps track of what the most recent changes are to the file.

Let’s say you create a shared library and then run some tests. Next, you decide to add some more code to your functions in the shared library. Well, when you recompile, the compilation process just appends the recent changes to the cache versus having to recompile everything all over again as you would in a static library creation.

Src

How to create a shared library?

So lets say we have a couple of files that we want to turn into a shared library…

file0.c file1.c file2.c and a header file fheader.h

each of those functions serve their own purpose and their prototypes are included in the header file.

To create the shared library lets run this command

$ gcc -fPIC -Wall -Werror -Wextra -pedantic *.c -shared -o libfile.so

  • The -fPIC flag enables position independent code, which allows the code to be located at any virtual address at runtime.
  • -Wall enables all warnings our compiler could throw.
  • -Werror turns all warnings into errors (won’t compile until errors fixed).
  • -Wextra ensures that type comparisons are valid.
  • -pedantic makes sure that the code follows ISO standards.
  • The -shared flag indicates that we want to create a shared library which has the file extension .so.
  • The -o flag allows us to name the output file ourselves.
  • Final result: libfile.so

Why are they useful?

So going back to our files example in the previous section let’s say we created another file called file3.c that relies on another file’s prototype. We want to add this new code to the repository we have but we need to compile it first. We would want to use a dynamic library since we are probably going to be adding more files in the future. See below:

$ gcc -Wall -Werror -Wextra -pedantic -L. file3.c libfile -o foo

  • -L. tells the linker that the library is located in the current directory.
  • file3.c is the file that references the shared library to execute our program in the #include “header.h” statement.
  • -libfile flag is the shared library we want to use.
  • -o flag is to create an executable filename foo that references library .so file.

Next, we need to set our environment variable LD_LIBRARY_PATH to our .so file so that the compiler can link during runtime. See below:

$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

Next, we need to install it in our object files directory on our Linux machine:

$ export LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH


How is it different than a static library?

Static libraries are fast and all prototypes are isolated to one file, but, you have to constantly load the file during compilation. Also, the executable file is larger in size since that library is included in it. This makes it a great choice for embedded systems type applications because the entire programs “ecosystem” needs to reside in one area. For example, a pacemaker is surgically installed in a human and the device needs access to the entire library since it will be performing operations (no pun intended :) ). You need to entire library to be linked to your executable file and all located in the memory of the device now implanted inside of the human.

Dynamic libraries have a slower execution time and are prone to compatibility issues, but, they are really fast in the compilation time and make the executable file smaller in size (since they don’t have that massive library file to create tons of overhead). This could have advantages in embedded systems when there is a connection to the updated files and the executable needs to be size conscious.

Src

Connor Brereton

Written by

Software Engineer & ex-Data Scientist @CiscoSystems | Studied Computer Engineering @SantaClara | Writer @TDataScience

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade