What is the runtime performance cost of including

2019-05-11 13:53发布

This question already has an answer here:

Is there any runtime performance difference between including an entire library (with probably hundreds of functions) and then using only a single function like:

#include<foo>

int main(int argc, char *argv[]) {
    bar();//from library foo
    return 0;
}

And between pasting the relevant code fragment from the library directly into the code, like:

void bar() {
...
}

int main(int argc, char *argv[]) {
    bar();//defined just above
    return 0;
}

What would prevent me from mindlessly including all of my favourite (and most frequently used) libraries in the beginning of my C files? This popular thread C/C++: Detecting superfluous #includes? suggests that the compilation time would increase. But would the compiled binary be any different? Would the second program actually outperform the first one?


Related: what does #include <stdio.h> really do in a c program

Edit: the question here is different from the related Will there be a performance hit on including unused header files in C/C++? question as here there is a single file included. I am asking here if including a single file is any different from copy-pasting the actually used code fragments into the source. I have slightly adjusted the title to reflect this difference.

4条回答
爷、活的狠高调
2楼-- · 2019-05-11 14:15

It depends greatly on the libraries and how they are structured, and possible on the compiler implementation.

The linker (ld) will only assemble code from the library that is referenced by the code, so if you have two functions a and b in a library, but only have references to a then function b may not be in the final code at all.

Header files (include), if they only contain declarations, and if the declarations does not result in references to the library, then you should not see any difference between just typing out the parts you need (as per your example) and including the entire header file.

Historically, the linker ld would pull code by the files, so as along as every function a and b was in different files when the library was created there would be no implications at all.

However, if the library is not carefully constructed, or if the compiler implementation does pull in every single bit of code from the lib whether needed or not, then you could have performance implications, as your code will be bigger and may be harder to fit into CPU cache, and the CPU execution pipeline would have to occasional wait to fetch instructions from main memory rather than from cache.

查看更多
叼着烟拽天下
3楼-- · 2019-05-11 14:19

There is no performance difference as far as the final program is concerned. The linker will only link functions that are actually used to your program. Unused functions present in the library will not get linked.

If you include a lot of libraries, it might take longer time to compile the program.

The main reason why you shouldn't include all your "favourite libraries" is program design. Your file shouldn't include anything except the resources it is using, to reduce dependencies between files. The less your file knows about the rest of the program, the better. It should be as autonomous as possible.

查看更多
Explosion°爆炸
4楼-- · 2019-05-11 14:19

It depends heavily on the libraries in question.

They might initialize global state which would slow down the startup and/or shutdown of the program. Or they might start threads that do something in parallel to your code. If you have multiple threads, this might impact performance, too.

Some libraries might even modify existing library functions. Maybe to collect statistics about memory or thread usage or for security auditing purposes.

查看更多
爷、活的狠高调
5楼-- · 2019-05-11 14:27

This is not such simply question and so does not deserve a simple answer. There are a number of things that you may need to consider when determining what is more performant.

  1. Your Compiler And Linker: Different compilers will optimize in different ways. This is something that is easily overlooked, and can cause some issues when making generalisations. For the most part modern compilers and linkers will optimize the binary to only include what is 100% necessary for executions. However not all compilers will optimize your binary.
  2. Dynamic Linking: There are two types of linking when using other libraries. They behave in similar ways however are fundamentally different. When you link against a dynamic library the library will remain separate from the program and only execute at runtime. Dynamic libraries are usually known as shared libraries and are therefore should be treated as if they are used by multiple binaries. Because these libraries are often shared, the linker will not remove any functionality from the library as the linker does not know what parts of that library will be needed by all binaries within that system or OS. Because of this a binary linked against a dynamic library will have a small performance hit, especially immediately after starting the program. This performance hit will increase with the number of dynamic linkages.
  3. Static Linking: When you link a binary against a static library (with an optimizing linker) the linker will 'know' what functionality you will need from that particular library and will remove functionality that will not be used in your resulting binary. Because of this the binary will become more efficient and therefore more performant. This does however come at a cost.

    e.g.

    Say you have a an operating system that uses a library extensively throughout a large number of binaries throughout the entire system. If you were to build that library as a shared library, all binaries will share that library, whilst perhaps using different functionality. Now say you statically link every binary against a library. You would end up with and extensively large duplication of binary functionality, as each binary would have a copy of the functionality it needed from that library.

Conclusion: It is worth noting that before asking the question what will make my program more performant, you should probably ask yourself what is more performant in your case. Is your program intended to take up the majority of your CPU time, probably go for a statically linked library. If your program is only run occasionally, probably go for a dynamically linked library to reduce disk usage. It is also worth noting that using a header based library will only give you a very marginal (if at all) performance gain over a statically linked binary, and will greatly increase your compilation time.

查看更多
登录 后发表回答