静态与动态库性能

kum*_*mar 7 windows static dynamic

一般认为静态库的性能大于动态库的性能.我的问题是:一旦dll已经加载到内存中,它还依赖于它吗?我的意思是,一旦初始化和所有事情发生,动态库的函数调用和执行是否比静态库需要更长的时间?

Fra*_*nov 12

免责声明:我是一个Linux-fu蚱蜢,因此可能存在一些不准确的地方(或者到处都是).但一般的想法应该是相对正确的.如果不是,我相信好的SO人会迅速纠正我.:-)

哦,我提供的链接是以Windows为中心的.如果有人能提供正确的以Linux为中心的链接,我将不胜感激.

简短的回答:可能.但是,即使这样,性能差异也可以忽略不计.

链接静态库时,编译器会生成代码以直接执行所有函数调用.创建进程并执行该代码时,函数调用是一个简单的调用指令.

使用动态库时,成本取决于您使用的是加载时动态链接还是运行时动态链接.

通过加载时动态链接,编译器仍会生成直接调用函数的代码,就好像它是静态链接的一样.当进程加载器加载DLL时,它将调用运行时链接程序来修复进程内存,以便这些调用直接进入实际的函数实现.这必须在从加载的库中调用函数之前发生.在Windows上,它由NT DLL加载器完成,它在进程初始化时调用DLL上的LoadLibrary.在Linux上,它由运行时链接程序ld-linux.so完成.

使用加载时动态链接,该过程基本相同,除了编译器生成调用小存根的代码,这将检查库是否加载,如果没有,将调用NT DLL加载器.因此,DLL将按需加载,并且进程加载器不必在进程初始化时加载它.这样可以加快进程启动时间,但通话性能仍然相同.(但请注意,延迟负载存在其他缺点)/DELAYLOAD

我不知道是否有相应的Linux支持,但如果没有,我会感到惊讶.

通过运行时动态链接,您的代码维护函数指针并决定何时卸载库.在Windows上,它必须使用LoadLibrary和GetProcAddress,在Linux上它是dlopen,dlsym和dlclose.在任何情况下,对进程启动时间的影响与延迟负载加载时动态链接的含义相同; 但是,在每个方法调用上取消引用的指针确实增加了一个可忽略不计的小成本.(虽然如果你知道自己在做什么,你可能会疯狂并修复你的进程内存以避免指针解除引用.然而,这样做的努力比你获得的性能要好一个数量级.它.)

  • 是的,我的第一个与Linux相关的严肃答案!Downvotes欢迎,但请告诉我我错在哪里!:-) (2认同)

dan*_*rth 5

我认为在性能方面最大的区别在于,使用静态库,编译器可以优化对库的函数调用,但在动态库中,编译器对其调用的函数的行为一无所知。