在Objective-C中包含头文件的成本

时间:2021-01-28 15:06:02

This may seem like a really stupid question, but what is the cost of including (actually, calling #import) a header file in Objective-C? I get tired of constantly including the same headers in various locations, so I decided to simply create a GlobalReferences.h file that includes several commonly-referenced headers.

这似乎是一个非常愚蠢的问题,但是在Objective-C中包含(实际上,调用#import)头文件的成本是多少?我厌倦了在不同的位置不断包含相同的标题,所以我决定简单地创建一个包含几个常用标题的GlobalReferences.h文件。

Is there any appreciable cost for including references to other files if they aren't even used? My gut tells me "no" as it seems like the linker is just made aware of other files when using #import, but I wasn't sure if special considerations need to be taken for iPhone development, which is what my project concerns. Any thoughts?

如果不使用其他文件,是否包含对其他文件的引用有明显的成本?我的直觉告诉我“不”,因为在使用#import时,链接器似乎只是意识到其他文件,但我不确定是否需要特别考虑iPhone开发,这是我的项目所关注的。有什么想法吗?

6 个解决方案

#1


7  

The linker knows nothing about #imported files. In fact, the Objective-C compiler knows nothing about them either, they are preprocessed out by the preprocessor. The preprocessor effectively inserts the contents of the headers into the point you've included them in your source file. The actual Objective-C compiler will then have to process extra function prototypes and class interface definitions even though they aren't being used. Though this is not usually a lengthy task, it can increase compile times. The resulting size and performance of your application should remain unaffected.

链接器对#imported文件一无所知。实际上,Objective-C编译器对它们一无所知,它们由预处理器预处理。预处理器有效地将标题的内容插入到源文件中包含它们的点。然后,实际的Objective-C编译器必须处理额外的函数原型和类接口定义,即使它们没有被使用。虽然这通常不是一项冗长的任务,但它可以增加编译时间。应用程序的最终大小和性能应保持不受影响。

To see what the raw source code looks like (including all header files and expanded macros etc):

要查看原始源代码的外观(包括所有头文件和扩展宏等):

gcc -E your-source-file.m

#2


3  

Importing/including more header files than you need will increase compile times. You can alleviate some of this pain with pre-compiled headers.

导入/包含比您需要的更多头文件将增加编译时间。您可以使用预编译的标头缓解一些痛苦。

#3


2  

The biggest drawback will be in compilation times. If all of your headers are imported in every source file, then the entire project will have to be rebuilt every time you make a change to a header file.

最大的缺点是编译时间。如果在每个源文件中导入了所有标头,则每次更改头文件时都必须重建整个项目。

#4


1  

I was under the impression that it wouldnt be too much of a hit: http://en.wikipedia.org/wiki/Objective-C#.23import

我的印象是它不会太受欢迎:http://en.wikipedia.org/wiki/Objective-C#.23import

#5


1  

what is the cost of including (actually, calling #import) a header file in Objective-C?

在Objective-C中包含(实际上,调用#import)头文件的成本是多少?

The compiler may run out to read these files unnecessarily. Once #imported, the additional files will need to be parsed, compiled, etc. for each translation (e.g. .m file) it is visible in -- making your build and link times much longer. 10 times longer is not surprising.

编译器可能会用完而不必要地读取这些文件。一旦#imported,就需要对每个翻译(例如.m文件)进行解析,编译等附加文件,这样可以使您的构建和链接时间更长。 10倍长并不奇怪。

I get tired of constantly including the same headers in various locations, so I decided to simply create a GlobalReferences.h file that includes several commonly-referenced headers.

我厌倦了在不同的位置不断包含相同的标题,所以我决定简单地创建一个包含几个常用标题的GlobalReferences.h文件。

Typically, that's a very bad approach. The common problem is that whenever any of the files included by GlobalReferences.h is changed, your whole project and all in-between dependencies would need to be rebuilt, relinked, etc.

通常,这是一种非常糟糕的方法。常见的问题是,只要GlobalReferences.h包含的任何文件发生更改,您的整个项目和所有中间依赖项都需要重建,重新链接等。

My preference is to separate programs into little libraries or packages where this interdependence exists (e.g. StoreKit.framework is a little package/library) -- but stuffing those libraries/frameworks/packages in headers solves nothing. Also, forward declarations and storing your data in the class continuation or @implementation can significantly reduce dependencies (because you can localize the inclusion of a library/header to only the necessary translations).

我倾向于将程序分成几个存在这种相互依赖性的小库或包(例如StoreKit.framework是一个小包/库) - 但是在头文件中填充这些库/框架/包什么也解决不了。此外,在类继续或@implementation中转发声明和存储数据可以显着减少依赖性(因为您可以将库/头的包含本地化为仅必要的转换)。

Lastly, cleaning up after lazy includes is very time consuming, especially when there are many and you've waited until your project's build times are unbearably slow. Basically, you have to go back and pick apart unnecessary dependencies, rebuild, repeat (for days).

最后,在懒惰包含之后清理是非常耗时的,特别是当有很多并且你等到你的项目的构建时间无法忍受缓慢时。基本上,你必须回去挑选不必要的依赖,重建,重复(几天)。

Is there any appreciable cost for including references to other files if they aren't even used?

如果不使用其他文件,是否包含对其他文件的引用有明显的成本?

Absolutely. The larger your projects grow, the worse lazy inclusion becomes. A few lazy includes in a large project could add tens or hundreds of thousands of lines to most of your compiled files, and can trigger frequent recompilation of many sources. This adds a significant amount of complexity to the build process -- CPU demands go way up, RAM usage goes way up, disk IO goes way up… and again, this becomes a bigger problem as your codebases/projects increase in complexity.

绝对。你的项目越大,懒惰的包容就越差。大型项目中的一些惰性包含可能会为大多数已编译文件添加数十或数十万行,并且可能会频繁重新编译许多源。这给构建过程增加了大量的复杂性 - CPU需求不断增加,RAM使用率上升,磁盘IO上升......再次,随着代码库/项目复杂性的增加,这将成为一个更大的问题。

#6


0  

Go ahead and do it. Unless the headers you're including are massive and you're not using precompiled headers, you shouldn't see any difference. As others have said, #import is a preprocessor directive. This has no runtime consequence and in many cases no significant compile time consequence.

来吧,做吧。除非您所包含的标头很大并且您没有使用预编译标头,否则您不应该看到任何差异。正如其他人所说,#import是一个预处理器指令。这没有运行时结果,并且在许多情况下没有显着的编译时间结果。

#1


7  

The linker knows nothing about #imported files. In fact, the Objective-C compiler knows nothing about them either, they are preprocessed out by the preprocessor. The preprocessor effectively inserts the contents of the headers into the point you've included them in your source file. The actual Objective-C compiler will then have to process extra function prototypes and class interface definitions even though they aren't being used. Though this is not usually a lengthy task, it can increase compile times. The resulting size and performance of your application should remain unaffected.

链接器对#imported文件一无所知。实际上,Objective-C编译器对它们一无所知,它们由预处理器预处理。预处理器有效地将标题的内容插入到源文件中包含它们的点。然后,实际的Objective-C编译器必须处理额外的函数原型和类接口定义,即使它们没有被使用。虽然这通常不是一项冗长的任务,但它可以增加编译时间。应用程序的最终大小和性能应保持不受影响。

To see what the raw source code looks like (including all header files and expanded macros etc):

要查看原始源代码的外观(包括所有头文件和扩展宏等):

gcc -E your-source-file.m

#2


3  

Importing/including more header files than you need will increase compile times. You can alleviate some of this pain with pre-compiled headers.

导入/包含比您需要的更多头文件将增加编译时间。您可以使用预编译的标头缓解一些痛苦。

#3


2  

The biggest drawback will be in compilation times. If all of your headers are imported in every source file, then the entire project will have to be rebuilt every time you make a change to a header file.

最大的缺点是编译时间。如果在每个源文件中导入了所有标头,则每次更改头文件时都必须重建整个项目。

#4


1  

I was under the impression that it wouldnt be too much of a hit: http://en.wikipedia.org/wiki/Objective-C#.23import

我的印象是它不会太受欢迎:http://en.wikipedia.org/wiki/Objective-C#.23import

#5


1  

what is the cost of including (actually, calling #import) a header file in Objective-C?

在Objective-C中包含(实际上,调用#import)头文件的成本是多少?

The compiler may run out to read these files unnecessarily. Once #imported, the additional files will need to be parsed, compiled, etc. for each translation (e.g. .m file) it is visible in -- making your build and link times much longer. 10 times longer is not surprising.

编译器可能会用完而不必要地读取这些文件。一旦#imported,就需要对每个翻译(例如.m文件)进行解析,编译等附加文件,这样可以使您的构建和链接时间更长。 10倍长并不奇怪。

I get tired of constantly including the same headers in various locations, so I decided to simply create a GlobalReferences.h file that includes several commonly-referenced headers.

我厌倦了在不同的位置不断包含相同的标题,所以我决定简单地创建一个包含几个常用标题的GlobalReferences.h文件。

Typically, that's a very bad approach. The common problem is that whenever any of the files included by GlobalReferences.h is changed, your whole project and all in-between dependencies would need to be rebuilt, relinked, etc.

通常,这是一种非常糟糕的方法。常见的问题是,只要GlobalReferences.h包含的任何文件发生更改,您的整个项目和所有中间依赖项都需要重建,重新链接等。

My preference is to separate programs into little libraries or packages where this interdependence exists (e.g. StoreKit.framework is a little package/library) -- but stuffing those libraries/frameworks/packages in headers solves nothing. Also, forward declarations and storing your data in the class continuation or @implementation can significantly reduce dependencies (because you can localize the inclusion of a library/header to only the necessary translations).

我倾向于将程序分成几个存在这种相互依赖性的小库或包(例如StoreKit.framework是一个小包/库) - 但是在头文件中填充这些库/框架/包什么也解决不了。此外,在类继续或@implementation中转发声明和存储数据可以显着减少依赖性(因为您可以将库/头的包含本地化为仅必要的转换)。

Lastly, cleaning up after lazy includes is very time consuming, especially when there are many and you've waited until your project's build times are unbearably slow. Basically, you have to go back and pick apart unnecessary dependencies, rebuild, repeat (for days).

最后,在懒惰包含之后清理是非常耗时的,特别是当有很多并且你等到你的项目的构建时间无法忍受缓慢时。基本上,你必须回去挑选不必要的依赖,重建,重复(几天)。

Is there any appreciable cost for including references to other files if they aren't even used?

如果不使用其他文件,是否包含对其他文件的引用有明显的成本?

Absolutely. The larger your projects grow, the worse lazy inclusion becomes. A few lazy includes in a large project could add tens or hundreds of thousands of lines to most of your compiled files, and can trigger frequent recompilation of many sources. This adds a significant amount of complexity to the build process -- CPU demands go way up, RAM usage goes way up, disk IO goes way up… and again, this becomes a bigger problem as your codebases/projects increase in complexity.

绝对。你的项目越大,懒惰的包容就越差。大型项目中的一些惰性包含可能会为大多数已编译文件添加数十或数十万行,并且可能会频繁重新编译许多源。这给构建过程增加了大量的复杂性 - CPU需求不断增加,RAM使用率上升,磁盘IO上升......再次,随着代码库/项目复杂性的增加,这将成为一个更大的问题。

#6


0  

Go ahead and do it. Unless the headers you're including are massive and you're not using precompiled headers, you shouldn't see any difference. As others have said, #import is a preprocessor directive. This has no runtime consequence and in many cases no significant compile time consequence.

来吧,做吧。除非您所包含的标头很大并且您没有使用预编译标头,否则您不应该看到任何差异。正如其他人所说,#import是一个预处理器指令。这没有运行时结果,并且在许多情况下没有显着的编译时间结果。