静态库的性能高于动态库,这是一个普遍的概念。我的问题是:它是否也依赖于dll是否已经加载到内存中?我的意思是,一旦初始化和所有的事情都发生了,在动态库的情况下,函数调用和执行是否比静态库花费更长的时间?
发布于 2010-12-08 15:18:48
免责声明:我是一名Linux-fu蝗虫,所以可能会有一些不准确的地方(或任何地方)。但是一般的想法应该是相对correct.Sort的。如果不是这样,我相信人们会很快纠正我的错误。:-)
哦,我提供的链接是以Windows为中心的。如果有人能提供正确的以Linux为中心的链接,我将不胜感激。
简而言之:有可能。然而,即使是这样,性能差异也是微不足道的。
当您链接静态库时,编译器会生成代码来直接执行所有函数调用。当创建进程并执行该代码时,函数调用是一个简单的调用指令。
使用动态库时,成本取决于您使用的是加载时动态链接还是运行时动态链接。
使用,编译器仍然会生成代码来直接调用函数,就好像它是静态链接的一样。当进程加载器加载DLL时,它将调用运行时链接器来修复进程内存,以便这些调用直接转到实际的函数实现。这必须在调用所加载的库中的函数之前发生。在Windows上,它是由NT加载程序完成的,它在进程初始化时调用DLL上的LoadLibrary。在Linux上,它是由运行时链接器ld-linux.so完成的。
使用/DELAYLOAD加载时动态链接,过程本质上是相同的,除了编译器生成代码来调用小存根,该代码将检查库是否已加载,如果没有,将调用NT加载器。因此,DLL将按需加载,进程加载程序不必在进程初始化时加载它。这会导致进程启动时间更快,但呼叫性能仍保持不变。(但请注意,延迟加载还存在其他缺点)
我不知道是否有相应的Linux支持,但如果没有,我会感到惊讶。
使用,您的代码维护函数指针并决定何时加载该库。在Windows上,它必须使用LoadLibrary和GetProcAddress,在Linux上,它是dlopen、dlsym和dlclose。在任何情况下,对进程启动时间的影响与对延迟加载加载时动态链接的影响是相同的;但是,在每个方法调用上取消对指针的引用确实增加了可以忽略不计的小成本。(尽管如果您知道自己在做什么,您可以疯狂地修复您的进程内存,以避免指针取消引用。然而,正确地做这件事的努力比你这样做所带来的性能好处要大一个数量级。)
发布于 2010-12-08 15:29:05
我认为,在性能方面,最大的区别是,使用静态库,编译器可以优化对库的函数调用,但在动态库中,编译器对正在调用的函数的行为一无所知。
发布于 2017-08-01 16:42:22
DLL或静态库中的机器代码本身具有相同的性能。但是,编译器可以使用静态库更积极地优化可执行文件,特别是在启用链接时代码生成的情况下。当一起使用时,可以考虑删除不使用的变量和重复的代码,以及将代码放在彼此靠近的位置(请参阅PGO)。
当代码在应用程序之间共享时,从系统性能的角度来看,最好使用DLL,因为系统的总体内存压力较小(当操作系统能够跨进程映射内存区的视图时,Windows就是这样做的)。
https://stackoverflow.com/questions/4384752
复制相似问题