Could Xcode affect app performance while debugging? - ios

I have an application written in Swift on SceneKit + Metal. When I build and run the app from Xcode fps counter shows 40fps. But if I run the app myself by tapping the icon on springboard fps counter shows 60fps. How could it be? Could Xcode somehow affect app performance while debugging? I have no idea how this all works, but I suppose there could be some hooks for debugging to work correctly which affect performance. If so, can I opt-in from this?
I'm aware of different build flags for debug and release builds, but I don't make release build. Performance differs in the same debug build while running from Xcode vs when I run the app manually on the phone.

By default, Xcode enables the Metal validation layer. That does a bunch of additional checking of how you're using it to catch incorrect uses. The additional checking is slow, which is why Metal doesn't do it unless validation is enabled.
This can be changed in Xcode's Scheme editor. This is documented in Apple's Metal Programming Guide.

A nice tutorial on iOS Assembly. This might be insightful on the topic
As stated, this is because the compiler is in debug mode, meaning no optimizations are made. If you turn optimizations on, then you’ll see a much smaller function generated.
And also check out this answer about changing optimization levels.

I've experimented with different options in scheme editor and have find out that Debug executable checkbox affected performance in my case. So my assumption about debugger was right, but I didn't know about that checkbox before.

Related

Swift app function not called in release mode

I have a iOS Swift app. I recently added a feature and uploaded the new version to TestFlight. For some reason, the main function for this new feature is not being called in release mode, but works perfectly in debug mode.
What I tried so far: within 'Apple LLVM 6.0 - Code Generation' for Release
1) Changed Optimization Level to None, and
2) Changed 'Symbols Hidden By Default' to No
I do not believe that the function's specifics matter here, but for what it's worth: it receives and manipulates some JSON data from the backend. I have ten other functions which do exactly the same thing for different types of data - not facing the same problem there.
Any ideas around this? What other differences are there between Release Mode and Debug Mode? that might be a good start to troubleshoot.
Thanks,
What other differences are there between Release Mode and Debug Mode?
Aside from different device architectures, there's a DEBUG preprocessor macro that is excluded in Release.
You can make a scheme that allows you to debug in Release mode, and check where it breaks.
Assertions will not run in release mode. Sometimes people make this mistake (I've made it a few times over the years):
assert(doSomethingImportant(), "Failed")
This works in Debug, but doSomethingImportant doesn't get called in Release.

Swift app only performing reasonably when built for Xcode's Time Profiler?

I'm working on an app that processes large float arrays, and I was extremely disappointed to find that Swift is apparently a good 10x slower than Python when running on my iPhone 5. I guess that can't be true, but I would have thought it true had I not tested the app in the Time Profiler and realized that it's probably not my algorithm or Swift's implementation causing the issues.
When the app is built for the profiler, it performs nicely: It does the processing in an imperceptibly small amount of time, as it should. But normally, if I hit the run button (play symbol) in Xcode to build and run, even with the compiler set to be Fastest, it takes almost 20 seconds to complete. (Code remains unchanged between builds.) It's ridiculously slow.
It's reasonably fast when I build and run in a simulator on my MacBook Pro, but even then it's slower than it is when built and run through the Time Profiler on my little iPhone 5.
The performance difference between builds is also present when I place the following test code in the application() function in AppDelegate, so I don't think it's a GUI/threading issue or anything. And the same test code runs quickly when implemented in Objective-C (in a separate app on my device) and Python on my Mac.
var nums: [Float] = []
for var i = 0; i < 250000; i++ {
nums.append(Float(i) * 0.001)
}
(This takes around 20 seconds unless run through the Time Profiler.)
Have any of you experienced anything like this before? I'd be immensely happy if you could help me figure this out.
You were building the app in Debug mode instead of Release mode. Debug mode is much easier to debug, but release mode generates faster code.
When building for Debug mode, the compiler inserts special debug symbols that help the debugger. I once tried to debug an app in Release mode and the debugger couldn't even find my variables. Release mode not only doesn't include those symbols, but it also optimizes your app, generating a binary that is much smaller and faster.
Here's how to switch between Debug and Release mode:
Click on your scheme in the top-left corner of Xcode.
Select "Edit Scheme..."
Click on the "Build Configuration" dropdown.
Change the build configuration to Release.
Rebuild your project.
(I am not providing an image here because I assume you know how to rebuild your project.)

Compiling and running the metal examples

It has been a while since I have used XCode, but since Apple revieled XCode 6 and the new Metal API I had to check it out.
They have released examples, e.g. a converted version of their Basic3D example. I am having problems making them compile and run, though. I had to add paths the Quatz and Metal frameworks for compilation and linking to work - thought that should have worked out of the box with build-in libraries?
Also the metal shader compilation step fails, it can not find the metal compiler. Where in XCode is that path setup?
If I ignore the shader compilation step I get an error that the application will not run on any of the simulators. Can metal based 3D applications only run on actual hardware and not in simulator mode?
According to a staff on Apple dev forums, Metal does not run in the simulator.
See: https://devforums.apple.com/message/971605#971605
If you look at other samples/app templates there is no need to explicitly link any framework, indeed everything runs out of the box.
You can't run metal on simulator but you can use this workaround so that it will still compile as long as you have a fallback for the code.
http://medium.com/#jscampbell/bare-metal-working-with-metal-and-the-simulator-70e085e3a45
I started with the hello triangle example they give you to download. It contains all the platform #if's you need to know about. I recommend you get that project and take a look.
https://developer.apple.com/documentation/metal/hello_triangle
#if TARGET_OS_SIMULATOR
#error No simulator support for Metal API. Must build for a device
#endif

CCParticleSystem and TestFlight build bug?

I'm not really sure if this question is answerable as I am completely puzzled by this. Maybe if someone had a similar issue and can maybe point something out?
So I used 4 different CCParticleSystem effects in my app which run perfectly fine when built and installed from xcode. However, when I build and upload for testflight and download to my device, one of the CCParticleSystem effects doesn't show up with the intended particle texture, but instead shows up as a square instead of the texture I provided.
All 3 other CCParticleSystem effects are working properly though, just not this one, which is puzzling me.
I used Particle Designer for all 4 particle effects.
Anyone have any issues like this? Thanks for reading.
In my experience there are a couple of things that can cause issues like this:
There could be a resource missing from your build that was present in a previous build. Sometimes builds from XCode to device ignore resource deletions and updates.
You can check for this by doing an uninstall from the device, a clean in XCode, and then rebuilding to see if that makes the XCode build consistent with the TestFlight build.
If that doesn't help, then check the target membership of your particle resource and verify that it has been included in every build target that it should be (if you have multiple build targets).
Note that as a general rule, it is a good idea to do a clean within XCode prior to building an archive for distribution. This should ensure that the archive is always built using the latest sources and resource files.

How do I reliably get Instruments 4.x to symbolicate?

I have a bit of a dilemma — no matter what I do, I cannot get Apple's Instruments.app to symbolicate any of the included instruments while I'm profiling on my devices (it works OK in the iOS Simulator).
I've tried just about everything I can think of, including:
Checking that I'm actually building a dSYM
Switching between Debug and Release build schemes
Making sure that the signing certificate being used in my Development cert
Adding and removing my Derived Data folder from Spotlight's Privacy list
Clean & Build before profiling
Removing the Derived Data folder before building and profiling
I'm not sure where to go from here — I had symbols for an hour or two earlier in the week, but I just can't get them to show up at all anymore. It would be great to figure out what the mystical incantation is to make Instruments always find my app's symbols.
In the File menu there is an option for Re-Symbolicate Document. Choosing this, you can find your binary in the list and use the Locate button to specify the location of the dSYM manually. There is also a checkbox here for using Spotlight to find the dSYM; it's possible it got deactivated if Spotlight was borked at some point but is now fixed.
It seems that you cannot do this while Instruments is actually instrumenting, but it does seem to keep the setting for the next time you hit Record. It does not, however, seem to remember the setting after you close Instruments.
Did you ensure you are signing the app with a development profile (as opposed to a distribution profile)?
Be aware that you are usually using release builds with instruments so make sure you didn't choose a distribution profile for your release configuration...
I've seen Instruments 4.2 fail to symbolicate several times with the correct dSYM file.
After saving and quit/restart Instruments, it will then symbolicate.
(Sometimes I'll capture a small sample and make sure it works before collecting large samples.)
Aside from xcode's tools, you can use atos: https://stackoverflow.com/a/4954949/312725
Be sure to take slide into account as well: https://stackoverflow.com/a/13576028/312725
(I'm adding this information to several related questions that are related to that, but aren't exactly duplicate questions. This is copy-pasted, it's a honest attempt to help someone who googled that question rather then spam.)

Resources