19
program should leave a background process running when it is not in use. The installation
of downloaded program updates should be postponed until the program is shut down and
restarted anyway.
3.5 Program loading
Often, it takes more time to load a program than to execute it. The load time can be
annoyingly high for programs that are based on big runtime frameworks, intermediate code,
interpreters, just-in-time compilers, etc., as is commonly the case with programs written in
Java, C#, Visual Basic, etc.
But program loading can be a time-consumer even for programs implemented in compiled
C++. This typically happens if the program uses a lot of runtime DLL's (dynamically linked
libraries, also called shared objects), resource files, configuration files, help files and
databases. The operating system may not load all the modules of a big program when the
program starts up. Some modules may be loaded only when they are needed, or they may
be swapped to the hard disk if the RAM size is insufficient.
The user expects immediate responses to simple actions like a key press or mouse move. It
is unacceptable to the user if such a response is delayed for several seconds because it
requires the loading of modules or resource files from disk. Memory-hungry applications
force the operating system to swap memory to disk. Memory swapping is a frequent cause
of unacceptably long response times to simple things like a mouse move or key press.
Avoid an excessive number of DLLs, configuration files, resource files, help files etc.
scattered around on the hard disk. A few files, preferably in the same directory as the .exe
file, is acceptable.
3.6 Dynamic linking and position-independent code
Function libraries can be implemented either as static link libraries (*.lib, *.a) or dynamic
link libraries, also called shared objects (*.dll, *.so). The mechanism of static linking is
that the linker extracts the functions that are needed from the library file and copies them
into the executable file. Only the executable file needs to be distributed to the end user.
Dynamic linking works differently. The link to a function in a dynamic library is resolved at
run time. Therefore, both the executable file and one or more DLLs are loaded into memory
when the program is run. Both the executable file and all the DLLs need to be distributed to
the end user.
The advantages of using static linking rather than dynamic linking are:
Static linking includes only the part of the library that is actually needed by the
application, while dynamic linking makes the entire library (or at least a large part of
it) load into memory even when just a single function is needed.
All the code is included in a single executable file when static linking is used. Dynamic
linking makes it necessary to load several files when the program is started.
It takes longer time to call a function in a dynamic link library than in a static link library
because it needs an extra jump through a pointer in an import table.
The memory space becomes more fragmented when the code is distributed between
multiple DLLs. The DLLs are always loaded at round memory addresses divisible by
the memory page size (4096). This will make all DLLs contend for the same cache
lines. This makes code caching and data caching less efficient.