Search code examples
c++objective-cxcodecompilationclang

How can Objc/C++ project compilation time be profiled/optimized?


My Objc/C++ project compilation time is too long. Even when Xcode is doing an incremental build, it can take e.g. 140s = 2.5 minutes.

The problem is, 2.5 minutes for an incremental build says me nothing of what can be improved. E.g. Xcode Report Navigator shows that some file is compiled in 4.2s:

enter image description here

How can I check if this file could be compiled in 2.1s? 0.3s? What are the constraints except of the number of symbols in a resulting binary?

I've heard a one should use modules to speedup incremental builds, but let's assume I'm trying to speedup compile time for already extracted module.


I've heard that there's some kind of the "symbol dependency graph", but haven't found any practical advice how to use it for troubleshooting compile-time issues.

I've tried such tools to uncover "symbol dependencies", but they seem too high-level (and the first one generated too big file to be opened with graphviz on MacOS):

  1. https://github.com/nst/objc_dep
  2. http://github.com/PaulTaykalo/objc-dependency-visualizer

Also I've seen such build flags for Swift: -warn-long-function-bodies=200 / -warn-long-expression-type-checking=200. These flags can mark long functions, but could they explain WHY those function are so long? E.g. maybe some for loop was written poorly, and a compiler has to optimize it for a faster execution. In such case, if a programmer wrote that loop in a more optimal way, a compiler wouldn't have to optimize it, and a programmer wouldn't wait for 1-2 seconds at each build.


So, let's say there's an Objc/C++ file which is compiled in N seconds. The questions are:

  1. How to see the "divided" time for this file? E.g. preprocessing a whole file: N/4 seconds, compile func1: N/4 seconds, compile func2: N/4 seconds, optimize an assembly: N/4 seconds.
  2. Are there clang utils for such thing?
  3. How to check if there's an unnesessary #include/#import which is slowing down compilation.
  4. Can a compilation time correlate to a number of warnings which Xcode has to print? (I know I can check it by eliminating the warnings, but there're C++ files with almost no warnings and even bigger compilation time).

I know it's a wide topic, so any links/advices are highly appreciated.


Solution

  • For a single compilation unit, Clang has -ftime-trace argument to activate time profiler.

    It will generate a JSON file that can be visualized as a flamegraph, for example in chrome://tracing

    graph

    The compilation time is split between frontend and backend. You can review all the headers included, and the time spent on parsing them.

    If you are in Xcode, and want to profile a single file: open last build in Xcode Report Navigator, and copy-paste the command line used to compile this file.

    Alternatively, you can add -ftime-trace to Clang compiler flags in Build Settings, so it will produce this profile for all compiled files (separate JSON trace for each compilation unit). Then you can review each trace individually, or get a summary with a tool like ClangBuildAnalyzer. You will have to manually remove JSON files from a previous build (or add a custom Build Phase, or invoke Clean Bulid Folder in Xcode).

    To clean up unneeded headers: just comment out all of them, and then uncomment one by one only those that reduce compilation errors.