How to decrease build times / speed up compile time in Xcode? - iphone

What strategies can be used in general to decrease build times for any Xcode project? I'm mostly interested in Xcode specific strategies.
I'm doing iPhone development using Xcode, and my project is slowly getting bigger and bigger. I find the compile / link phases are starting to take more time than I'd like.
Currently, I'm:
Using Static Libraries to make it so
most of my code doesn't need to be
compiled everytime I clean and build
my main project
Have removed most resources from my
application, and test with a hard
coded file system path in the iPhone
simulator whenever possible so my
resources don't have to constantly be
packaged as I make changes to them.
I've noticed that the "Checking Dependencies" phase seems to take longer than I'd like. Any tips to decrease that as well would be appreciated!

Often, the largest thing you can do is to control your inclusion of header files.
Including "extra" header files in source code dramatically slows down the compilation. This also tends to increase the time required for dependency checking.
Also, using forward declaration instead of having headers include other headers can dramatically reduce the number of dependencies, and help all of your timings.

I wrote an extensive blog post about how I improved the iOS development cycle at Spotify:
Shaving off 50% waiting time from the iOS Edit-Build-Test cycle
It boiled down to:
1) Stop generating dSYM bundles.
2) Avoid compiling with -O4 if using Clang.

Personally I switched compiler to LLVM-Clang for my Mac development projects and have seen a dramatic decrease in build times. There's also the LLVM-GCC compiler but I'm not sure this would help with build times, still that's something you can try too if LLVM-Clang does not work for iPhone app compilation.
I'm not 100% sure LLVM is supported for development on the iPhone but I think I remember reading in a news feed that it is. That's not an optimization you can implement in your code but it's worth the try!

The number of threads Xcode will use to perform tasks defaults to the same number of cores your CPU has. For example, a Mac with an Intel Core i7 has two cores, so by default Xcode will use a maximum of two threads. Since compile times are often I/O-bound rather than CPU-bound, increasing the number of threads Xcode uses can provide a significant performance boost for compiles.
Try configuring Xcode to use 3, 4 or 8 threads and see which one provides the best performance for your use case.
You can set the number of processes Xcode uses from Terminal as follows:
defaults write com.apple.Xcode PBXNumberOfParallelBuildSubtasks 4
Please see Xcode User Defaults for more information.

If you're not using 8GB of RAM, upgrade now.
I just upgraded my macbook pro from 4GB to 8GB. My project build time went from 2:10 to 0:45. I was floored by the improvement. It also makes web browsing for research snappier and general Xcode performance when indexing, etc.

Easy answer: add another machine running Xcode on your local network. Xcode incorporates distcc to do distributed compiles. It can even use Bonjour to find other build hosts, which simplifies the process of configuring this greatly. For large builds, distributing can get you a speed increase that is nearly linearly proportional to the number of build machines (2 machines takes half the time, three takes a third and so on).
To see how to set this up, you can consult this development doc. It also features other useful build time improvement strategies, such as using precompiled headers and predictive builds.
Edit: Sadly, it appears Apple has removed this feature as of Xcode 4.3: http://lists.apple.com/archives/xcode-users/2012/Mar/msg00048.html
Xcode 5 has a server version which can do CI, but I doubt this will confer any benefit for ad hoc developer builds. However, there are some unannounced features that should dramatically speed up build times.

I used a script to make use of a RAM drive, together with some "forward declarations" optimizations my project clean build time went from 53 seconds to 20 seconds.
I was tempted to get the Gui on the AppStore, but opted rather to
go for command line. I put the script as part of git repository.
To see the build times, enter this in a terminal:
"defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES"
Restart Xcode to notice the build times in the toolbar.
(this is my non clean build time using objective-c)
Adjust the script to your liking. - Note the script clears
the derived data folder.
#!/bin/sh
#2 GIG RAM
GIGA_BYTES=$((2*1024*1024*1024))
# a sector is 512 bytes
NUMSECTORS=$((${GIGA_BYTES}/512))
#ram disk
mydev=`hdiutil attach -nomount ram://$NUMSECTORS`
newfs_hfs $mydev
# make mount point
MOUNT_POINT=/Users/your_user_name/Library/Developer/Xcode/DerivedData
# *******************************************
# ** WARNING - MOUNT POINT WILL BE DELETED **
# *******************************************
rm -rf ${MOUNT_POINT}
mkdir -p ${MOUNT_POINT}
# mount
mount -t hfs $mydev ${MOUNT_POINT}
echo unmount $(MOUNT_POINT)
To see the effect and to control the RAM Drive:
mount - see mount points
umount mount_point - unmount point
diskutil list - see disks
diskutil eject /dev/diskX - eject the disk
df -ahl - see free space
NOTE:
I essentially use the hdiutil provided by macOs.
I tried switching the -kernel option (no swapping to disk) on but failed on my machine, saying it is not implemented.
Maybe the new OS coming soon we will see even more improvements as the new file system copy feature is really fast, and possibly makes this script redundant.

One huge tip to halve compile times (for iOS projects at least) is to set Build Settings / Architectures / Build Active Architecture Only to YES.
What this does (especially with the advent of 64-bit iPads/64-bit compiler) is to not build the binary for the architectures you're not currently using.
Make sure you remember to re-enable this setting on submission to the app store, or your binary will not validate.

You mentioned using static libs for your most-often used files to prevent compilation. You can accomplish something similar by putting headers to your code that it's frequently used but not in your static libs in the precompiled header. At least they'll only be compiled once.
Care must be taken to avoid issues if you have multiple compilation types across your project (e.g. Obj-C, Obj-C++, C++).

Hey there, I would recommend you to optimize your project's physical structure. There's some good reading about this ( at least in the C++ world ) , but I do objective-C and the same principles often apply.
Here's a great article about project's physical structure optimization, which tends to improve compile times
Games From Within: Physical Structure Part 1
Good luck :)

one word: TmpDisk
Use TmpDisk to Create a 1.5Gb RAM disk
Change Xcode > Preferences > Location > Derived Data to /Volumes/1.5Gb/xcode data
Enjoy the speed!

Quick Note Regarding 'Throw more hardware at it' approach..
SUMMARY: I experienced a SMALL speed increase from making a SIGNIFICANT hardware upgrade
Test: Build/Run the exact same project on cloned macbooks (where the only difference should be their hardware)
Old Macbook Air (1.86GHZ Core 2 Duo ONLY 2GB RAM)
vs
Brand New Macbook Pro (2.3GHZ Core i7 8GB RAM)
BUILDING ON IPHONE 3GS
Macbook Air 1:00 - 1:15
Macbook Pro ~1:00
=> 0 to 0:15 of speed increase
BUILDING ON IPHONE 4S
Macbook Pro ~0:35
Macbook Air ~0:50
=> ~15 seconds of speed increase **Partially tested: There DOES apear to a significant difference between build times for the SIMULATOR between the 2 machines
In my continued experience.. you WILL get a significant increase when making big changes in PHONE hardware (i.e. build time on a 3GS vs iphone 5 (or 4 for that matter)).. at least in my experience, the limiting factor was the phone hardware (not the computer hardware).
SO.. to get the fastest build time.. option1) write code and run in the simulater on a fast computer OR option 2) build on the device with the lastest iphone

If your whole project gets rebuilt every time you hit run, that's probably the bug in XCode 7.0 <= 8.1 giving you a hard time.
Creating the user defined build setting HEADERMAP_USES_VFS to YES cut the macbook compile time from 75 seconds each time, to 25 seconds. See Xcode 8 does full project rebuild for more info.

I switched to Hackintosh with a 5960x CPU, overclocked to 4.4GHz only to bring down Xcode compile time. That's 8 cores and 16 threads. Total cost $3000 for a computer that crushes all macs. However I've spent at least 10 days getting it set up, first with Yosemite, the. I had six months downtime when I couldn't update macOS while Xcode required a newer os. I just got it running sierra and life is good again.
My 2,8 GHz i7 double core 16 GB RAM MacBook Pro compiles my project in 75 seconds, the Hackintosh in 20 seconds. (Swift, dlib, opencv c++ in the project)
However the biggest problem is Xcode doesn't seem to use multiple threads when compiling swift. This is the bottleneck, I hope they will fix it soon.

Related

Android Emulator gets stuck (Using HAXM)

I recently read about the HAXM , followed the steps, for first few days emulator used to get started in less than minute but now it gets stuck at this point - as shown below.. although it shows correct time & clock remains working . The worst part is all of the emulators I create show same problem .Any solution ?
You can try couple of things here
Check the RAM size allocated for Emulator. The best RAM size recommended is around 512MB for an Emulator. Make sure you have set the appropriate RAM size
Kill all your emulators, restart your machine and create fresh AVDs
Is this happening with the same application or different ones? a little bit detail on the application will help in suggesting more work around.
a. If it is an OpenGL application choose use Host GPU on your AVD and also install the correct graphics driver on your host machine

Is there any limit to add object in NSMutableArray..?

Recently I'm working on project which requires a large no. of object should be added to an NSMutableArray.
I'm little bit confusing how much object we can add in NSMutableArray..?
Thanks in advance.
It's probably all dependent on memory. Older generation devices get a smaller share of RAM (memory) to use than newer devices for the apps they run. Therefore, the limit is probably lower on older devices than newer ones. That said, it probably can't be pinpointed to a specific number (unless I am mistaken).
Rather, what you should try to do is figure out if you can handle memory better here so you're not worried about a size limit :)
EDIT
From Steffen Itterheim's "Learn Cocos2D Game Development With iOS 5", based on the installed memory of a device, here are some rough estimates of the amount of memory apps can expect to work with:
128MB Installed => 35-40MB available, memory warnings at 20-25MB;
256MB Installed => 120-150MB available, mem warning at 80-90MB;
512 MB Installed => 340-370MB available, mem warning at 260-300MB.
Of course these are rough estimates, but depending on the device you can obviously see that the size of an NSMutableArray depends on the available memory

performance of iOS apps when compiling in debug or release / distribution mode

What are some performance differences when compiling your code in these mode?
debug
release / distribution
are the default settings optimized for app store (distribution)? what are some ways to optimize performance even more by tweaking the settings?
You'll need to compile your app in both configurations and run some performance tests to answer that question. The advantages gained are highly dependent on what the program does.
I've done some performance testing on CPU intensive code on Mac OS X for Project Euler problems and I've found that release applications are usually about twice as fast. However, as soon as you start doing IO or graphics, the advantage drops.

Emulate a slow iPhone

I have an iPhone app (Objective C++). My beta testers - some of them, not all of them - are complaining of slow startup, 7 to 10 seconds. On my device (it's a 3GS), it loads in about 2 sec. On the device simulator - even faster. As things stand now, I cannot even isolate the bottleneck.
Can I somehow slow down the simulator or a fast device? Setting the simulated hardware version to 2.0 does not help.
As a last resort, I could try and borrow an old, slow device from a friend for a night or two. But I'd rather not...
If I were you I'd try profiling the startup with Shark - it's hard to profile startup on the device, one way is to put a 5-6 second sleep statement in ApplicationDidFinishLaunching so you have time to attach Shark and start recording, don't make it too long though or the app will be killed!
Also consider what you are doing on startup that might be a lot longer for some people - looking at address records, or things like that.
Aral Balkan links to some nice tools by Mike Shrag that allow you to get the old slow motion simulation mode on triple shift working in SDK 3. Speedlimit - which allows you to throttle network bandwidth might be useful.
This is an old question, but one option is to use a non-SSD iMac or MBP to test on a slow environment. The latest Xcode versions and simulators (XC version 7 for sure) run extremely slowly on non-SSD devices. More slowly than any actual phone...

my iPhone software is so slow!

I ported one of my mac applications to the iphone. WOW!!! is it slow! At first I started thinking maybe I was doing a lot of disk access. But as I started looking I realized I simply do an offset read of a binary file. I only read in about 512 bytes of data. I also have an array that is huge. Maybe 2MB. But why would that be slow? It is perminatly located in memory.
I would love to hear some ideas from you all!
When you have major performance problems, the tool to pull out first is Instruments. Start with "Run With Performance Tool > CPU Sampler" and get a feel for where your app is spending its time. After that, check Object Allocations to see if you're hitting memory harder than you should. iPhone is a resource-constrained environment compared to the Mac. Things that you think of as fast can dramatically impact performance on iPhone. Disk access is much more expensive. Even allocating memory can be a significant impact (welcome to the world that server developers deal with every day). You only have one core, so things you stuck off on a background thread now compete with your main thread. It's a different world.
It's hard to debug the application over Stackoverflow, but there are many reasons why the iPhone app runs much slower: Your mac applications run on probably the latest CPUs with tons of memory, as for the iPhone it's very limited (3GS is rumored to have 600MHz CPU with 256MB RAM). Also, Mac applications are a bit more forgiving when it comes to memory usage; as for the iPhone it's important that only create the objects you need when you need them and release them when you no longer use them. Delaying object de-allocation results in some slowdown as well.
I recommend using Instruments performance profiling tool, that is bundled with XCode and the Developer tools. It'll give good tips on what the bottlenecks are.