我已阅读here关于在python中导入模块的内容。可以选择不导入整个模块(例如sys)并仅导入其中的一部分(例如sys.argv)。这可能在C?我可以只包含printf或任何其他函数的实现,而不是整个stdio.h库吗?
我问这个,因为在我只需要几行代码的地方包含一个完整的文件效率似乎非常低效。
我理解有可能仅包含函数本身不起作用,因为它依赖于其他函数,其他包括,定义和全局变量。我只是要求将它用于包含执行所需的所有数据的整个代码块。
答案 0 :(得分:2)
C没有任何与Python"等同的,甚至类似的东西......来自...... import"机构。
我问这个,因为在我只需要几行代码的地方包含一个完整的文件效率似乎非常低效。
实际上,当#include
文件导入宏的声明或其他地方声明的函数时,正常会发生什么。你没有导入任何可执行代码......所以"不必要的"包含对运行时代码大小或效率有零影响。
如果使用(即"调用")宏,则会导致宏体扩展,这会增加可执行代码的大小。
如果你调用一个你已经包含声明的函数,它将为call语句本身添加代码....但该功能并未扩展。而是一个"外部参考"添加到您的" .o"文件,当您从" .o"创建可执行文件时加载程序解析文件和依赖库。
答案 1 :(得分:1)
Python :" 有一个选项可以不导入整个模块" :我想你误解了这里发生了什么。指定要导入的名称时,表示只有那些名称进入您的名称空间。 "整体"编译模块,即使只指定一个名称,也会运行函数外的任何代码。
C :我将假设您使用的是UNIX / Linux / OS X或Windows等操作系统(以下内容不适用于嵌入式系统)。
最接近的C必须是import
是动态运行时链接。这不是标准C的一部分,它由操作系统定义。因此POSIX有一种机制,Windows有另一种机制。大多数人称这些库文件为#s; DLLs",但严格来说,这是一个Microsoft术语,它们是"共享对象" (.so)在UNIX类型系统上。
当进程附加到DLL或.so时,它被映射"进入虚拟内存的过程。这里的细节因操作系统而异,但基本上代码分为"页面",其大小各不相同,但32位系统为4kb,64位为16kb。只有那些需要的页面才会加载到内存中。当需要一个页面时,那就是所谓的"页面错误"发生,操作系统将从可执行文件或交换区域获取页面(取决于操作系统)。
此机制的一个优点是代码页可以在进程之间共享。因此,如果您有50个进程都使用相同的DLL(例如C运行时库),那么只有一个副本实际上被加载到内存中。它们共享一组页面(它们可以因为它们是只读的)。
在Python中没有类似的共享机制 - 除非模块本身是用C语言编写的,并且是DLL(.pyd)。
所有这些都是在不了解程序的情况下发生的。
编辑:查看其他答案我意识到您可能正在考虑将#include
预处理器指令合并到源代码中的头文件。假设这些是标准头文件,那么它们对可执行文件的大小没有影响,它们应该是" idempotent "。也就是说,它们仅包含预处理器,编译器或链接器使用的信息。如果头文件中有未使用的定义,则应该没有副作用。
将未使用的库(-l指令到编译器)链接起来会使可执行文件更大,这会使页面表更大,但除此之外如果不使用它们,那么它们不应该有任何显着差异。这是因为上面描述的按需页面加载(这个概念是在20世纪60年代在英国曼彻斯特发明的)。