Podcast Search

Developing Perspective

#83: Performance and Letting Go.

Select a time to play from there. The line being spoken is highlighted as the audio plays.

0:00:00Hello and welcome to Developing Perspective. Developing Perspective is a podcast discussing

0:00:04news of note to my office development Apple and like I'm your host David Smith. I'm an

0:00:08independent iOS and Mac developer based in her Virginia. This is show number 83 and today

0:00:12is Thursday, September 27th. Developing perspective is never longer than 15 minutes. So let's

0:00:17get started. Alright, so this is gonna be another one in the series of episodes I went

0:00:23to. I'm going to be talking about the weather app I'm working on. And I'm kind of excited

0:00:27because I think I'm ready to ship.

0:00:32And I'm recording this about 3 p.m. on Thursday,

0:00:35and I'll probably be submitting this evening.

0:00:39I did the always exciting thing where I take the version number

0:00:42of my app and bump it all up to 1.0, which is kind of exciting.

0:00:45I think it's basically ready.

0:00:50I've done my initial beta testing.

0:00:51I've done as much testing as I can.

0:00:53I have nothing left on my to-do list.

0:00:53And so I think it's just about ready.

0:00:55So I'll talk a little bit more about that later in the show.

0:00:58But to start with, I was going to talk about one of the activities

0:01:01that you'll do towards the end of actual app construction.

0:01:04And that's performance improvements and performance testing.

0:01:07And it's vitally important and kind of a tricky problem.

0:01:11And so that's why I was devoted at least half the show to kind of just

0:01:14talking about how I go about that and what that looks like.

0:01:17So performance is most often just sort of--

0:01:19you characterize it as making your app do the things it does quickly.

0:01:25And quickly is ideally defined as imperceptibly fast.

0:01:30So the goal would be that ideally the user never really is aware

0:01:34that any operation is taking time to perform.

0:01:36It just happens.

0:01:37It's instantaneous as far as possible.

0:01:42And there's a lot of tricks and things you can do to create either

0:01:46that illusion or performance enhancing techniques

0:01:51and approaches that you can do to make that the actual case.

0:01:54And so what I've done essentially is,

0:01:59as I've talked about, I've built the app,

0:02:01I prototyped it, I worked on the fun,

0:02:03sort of scaling on the feature set,

0:02:05understand exactly what it is I'm going to build,

0:02:07and then I started this process of refinement.

0:02:09And you kind of want to think about this as,

0:02:12if you've ever done carpentry with a sandpaper, right,

0:02:14where you're going to sit down and you have the basic form,

0:02:17it's right there, and all you're going to do

0:02:19is take some sandpaper and you're going to

0:02:22be starting to smooth it off.

0:02:23And your goal is to make it as silky smooth as possible.

0:02:26And the way you, if you've ever done any carpentry,

0:02:29the way that you go about doing that is you start off

0:02:31with a really rough sandpaper.

0:02:34And your goal is you're taking off big chunks of wood

0:02:37at a time, you're kind of really,

0:02:39you're not worried as much about the precision of that,

0:02:42you're just kind of going at it.

0:02:43And then as you get closer and closer to what you're trying to do, you're going to get finer

0:02:47and finer sandpaper, and you're going to be doing smaller and smaller adjustments.

0:02:51That's very similar to the approach I end up taking with performance improvement.

0:02:56What I want to do is, I want to start off with making any kind of huge improvements,

0:03:03big chunks, things that are going to have very big improvements and obvious advantages

0:03:08to the user.

0:03:09I want to do those first.

0:03:10and I want to get the groundwork of that going.

0:03:13And so the way I typically approach that is I'll just use the app

0:03:17and I'll be like, "Man, that's slow,"

0:03:19and just sort of start an approach on some particular small area of the app

0:03:24or some focused area of the app.

0:03:26The number one rule of performance improvement is measurement.

0:03:29If you don't measure what you're doing,

0:03:31you're probably going to drive yourself crazy

0:03:33and you're not really going to make progress on what's happening.

0:03:36By measurement, what I typically mean is either in instruments,

0:03:39instruments, looking at whatever memory performance, frames

0:03:42per second, the time profilers, stack trace,

0:03:46like those types of things.

0:03:48Or even just something as simple as grabbing the time

0:03:51before and after an operation completes

0:03:53and NS logging that to the console.

0:03:56But if you don't have a measurement of what your baseline

0:03:58is, then it's impossible to know if the improvements you're

0:04:01making are actually doing anything.

0:04:03And you'll just end up chasing your tail.

0:04:05If you're like, well, I think I changed-- when I made this

0:04:07change, I think that helped.

0:04:09But maybe I'll do this other thing, too.

0:04:10I may be able to do this other thing.

0:04:12And then the second rule is that you,

0:04:15in addition to measuring everything,

0:04:17you want to only ever change one thing at a time.

0:04:22And these two things go together,

0:04:23and they should make sense, that if you are changing two things

0:04:27at once, then you'll never know what's actually changing.

0:04:30Or worse, you make lots of changes at once

0:04:32and then kind of run through the app.

0:04:34It's almost impossible at that point

0:04:36to get a good sense of actually what's happening.

0:04:39And you're just going to drive yourself crazy.

0:04:41So for a performance measurement, like I said,

0:04:43I'll use a lot of instruments for a lot of it.

0:04:46And then the second thing that I do

0:04:48is just these print lines, and I'll

0:04:49have those all over the place.

0:04:51And so the first thing that I tackle--

0:04:53and this is probably, honestly, in my opinion,

0:04:56the most important thing that you

0:04:59can do for performance testing and improvement

0:05:03is that you want to focus on launch time.

0:05:05I think it's probably the most important bit of performance.

0:05:10I guess to me it's a bit strong.

0:05:12But it is certainly one of the most important areas

0:05:15of performance in your application

0:05:16because it's the user's first impression.

0:05:18And it's an impression that they're

0:05:20going to be making over and over and over again.

0:05:22Now, I know the app goes into a background state

0:05:24and may not actually be relaunched a lot.

0:05:26But I want that app's launch screen

0:05:29to disappear as quickly as possible.

0:05:31And the reason for that is that is, by definition,

0:05:34time that the user is wasting.

0:05:36There are a couple of areas in your app where it may be great

0:05:39or it can be faster at downloading stuff, faster

0:05:42at this, faster at that.

0:05:43But often those things are happening

0:05:45while the user can do something else

0:05:47or is looking at something else.

0:05:49But with launch time, that's it.

0:05:51All they can do is wait.

0:05:52They can't do anything else while that happens.

0:05:54So you want to make that as fast as possible.

0:05:57And the first rule of making your launch time fast

0:06:00is doing almost nothing on the main thread

0:06:04from application did finish launching to view did load,

0:06:08view did appear.

0:06:09And hopefully those terms make sense

0:06:10if you're an app developer.

0:06:11But basically from when your app starts

0:06:13until you have shown things and so you finish showing something

0:06:16on the screen, whatever that first thing is,

0:06:18you want to do as little as possible on the main thread.

0:06:21You want to put off as much as possible.

0:06:23You want to do as few-- the absolute minimum that you can.

0:06:26And that typically works out pretty well

0:06:28by just wrapping up code blocks, things that you need to do,

0:06:31and GCD queues, or just doing things where you can say,

0:06:35dispatch async on the main thread.

0:06:38And you're pushing these things off.

0:06:40So if you need them to happen up front,

0:06:42you need to do these things right away, do them early,

0:06:45but don't do them until you've started

0:06:47showing something to the user.

0:06:50It's just really important that you don't do that.

0:06:53And then the second thing that I do

0:06:55is you're trying to optimize that first view stack

0:06:59that you're going to show the user.

0:07:01And so being careful about what you're showing, how you do it,

0:07:05and the data you load and the data you need

0:07:07is all an important part of that.

0:07:09And I know for what I went through this process in my app,

0:07:13and I was able to get the launch experience on a 4S

0:07:18down in my naive, basic, simple solution.

0:07:21At one point, I think my launch time was about 2 and 1/2

0:07:24seconds.

0:07:25And I got it down to about 0.3 seconds

0:07:29by a lot of these things.

0:07:31So all those different things in aggregate.

0:07:32And then I was pleasantly surprised

0:07:34that when I got my iPhone 4-- or my iPhone 5,

0:07:38my launch time is now down to 0.1 seconds, which

0:07:43if you think about how short of a time that is,

0:07:46it's basically instantaneous.

0:07:48And it looks basically like the app launches immediately,

0:07:52which I'm really, really proud of.

0:07:54And I really like that part of it.

0:07:55That's something that I'm-- it's like I show off to people.

0:07:58It's like, let me quit the app in the multitasking

0:08:01and then started. Wow, see how fast that was. That's important to me because at no time

0:08:05someone on an iPhone 5 should ever have to wait a perceptible amount of time for the

0:08:12app to load. Another thing I'll say about this is I fall firmly in the camp of you want

0:08:18your launch image to be the empty state of your initial screen rather than a splash screen

0:08:25or a banner or a logo.

0:08:27And a big part of that is that really helps with the perceived

0:08:32load time of the application, because that

0:08:35will show instantaneously.

0:08:36And so it shows that, and then it shows your app.

0:08:39And so if those two things are the same,

0:08:42it almost looks like your app's loaded immediately.

0:08:45And just that extra 0.1, 0.2, 0.3 of a second

0:08:48that it took to actually load is just almost

0:08:51like you can make it look like an animation,

0:08:53that it was a launching animation, like your display is just fading in, rather than you

0:08:58actually were doing stuff in the background.

0:09:01So those are some of the things I do about performance. Basically, you just want to measure,

0:09:05and you want to change one thing. You just keep doing that, and you keep getting finer

0:09:09and finer grain. I mean, towards the end, I was changing just tiny little things, tweaking

0:09:13the way that I was saving files to disk, saving the way that the data structures that I was

0:09:20working with that I was saving the disk and my caching infrastructure. Anything that I

0:09:25could do to just squeeze and squeeze and squeeze, making sure that all of my networking calls

0:09:30as much as possible are gzipped so that I'm loading a small amount of data as possible,

0:09:35trying a bunch of different JSON libraries and frameworks to find the one that would

0:09:39work the best with my dataset. Because of course, typically, in my experience,

0:09:43NSJSON serialization, like the built-in one to the system, is pretty good. And in this

0:09:48In this case, for me, it actually turned out that was the best.

0:09:50But in my experience, it's possible that another library could be faster

0:09:56based on your data set, because they're all probably going to--

0:09:58they're making certain assumptions.

0:09:59They're all making different adjustments and things,

0:10:01how they're going to handle different encodings,

0:10:03how they're going to handle different data structures.

0:10:05And so you just-- you have to try these things to see which one's faster for you,

0:10:09not just which one's fastest based on benchmarks.

0:10:12And in the end, I'm very pleased with the performance of the app.

0:10:14I think it's fast. It's snappy.

0:10:16I was able to, on the 4S and 5, I have 60 frames a second animations everywhere.

0:10:22On the 4, I was able to get it to 40 frames a second, where at that point

0:10:25I just gave up.

0:10:26Because it's pretty smooth, but I couldn't quite get it more.

0:10:29And increasing-- the 4 is probably my performance baseline.

0:10:33And it is pretty good.

0:10:35It's visually smooth, but not as smooth as possible.

0:10:39And so that's kind of where I drew the line.

0:10:41But it's an important thing for performance.

0:10:43You don't want to go crazy and just constantly--

0:10:45Could we go down this rabbit hole?

0:10:47But once you ever get that good enough phase, it's great.

0:10:50And I think, like the app, I'm really

0:10:52proud of the performance of it just across the board.

0:10:55And so that brings me to the next thing.

0:10:57It's like I said, I'm basically getting ready to submit.

0:11:00The app I said is-- I think I mentioned before--

0:11:02is going to launch hopefully on October 17,

0:11:06which is in about 2 and 1/2 weeks-ish.

0:11:08It's about three weeks from yesterday.

0:11:10And I'm picking a date that's based on a variety of things.

0:11:13it's making sure I have enough time for app review to go through.

0:11:17And the way I tend to do it is I try and leave about two and a half weeks of time.

0:11:22App review on the iOS side has recently and typically been about a week.

0:11:26And so what I want to make sure is I always have enough time in it for two review cycles.

0:11:31So that's A, if they reject it for whatever reason, I mean, you never know.

0:11:36Like for some reason there's some weird bug that they find.

0:11:39You just got to account for that.

0:11:41And then two, it's so that if I submit it, they approve it,

0:11:46and I find a bug, I find a problem, a beta tester,

0:11:51a previewer, someone in the press finds some bug

0:11:55that I want out, I have an opportunity to resubmit

0:11:57and have that approved, hopefully, by the time

0:12:00that I'm aiming to launch.

0:12:02I'm picking a day specifically, so I can hopefully

0:12:04coordinate some marketing, some press, reaching out

0:12:06to my friends and colleagues and people to try

0:12:07I find building some buzz and promotion around it,

0:12:10and I find having a day in mind is very helpful for that,

0:12:13rather than just like, it'll launch at some point

0:12:15whenever it gets approved.

0:12:17And so I've set the release date to October 17th.

0:12:20Hopefully that ends up working out.

0:12:22Like I said, I'm submitting now.

0:12:24That's about three weeks.

0:12:25It should hopefully be OK in terms

0:12:27of getting that through App Review by then.

0:12:29But you just never know.

0:12:31But the funniest part, as I've been heading down this road,

0:12:33and it's been exciting, and I'm like, yeah, I'm getting close.

0:12:36narrowing in on finally being able to ship this thing.

0:12:39The hardest part, honestly, is letting go and trying not to feel overly protective of an application.

0:12:50So I've spent a good amount of time, it's probably about four weeks of work at this point,

0:12:55which is not a huge project, but it's a substantial investment in time and energy

0:13:00and various things I've bought in terms of graphics and fonts and all kinds of stuff to go into it.

0:13:05But there's something scary about letting other people see it.

0:13:10There's something scary about having other people look at it, and especially other people

0:13:16to critique it, to say what they think about it.

0:13:19Because obviously I think it's great, and you start off showing it to people who you

0:13:24know.

0:13:25So if you start off with people who love you, your family, your spouse, those types of people,

0:13:31And then you tend to move out to people who like you, your friends.

0:13:35And then you start to get into the scary part where you start to get into the people you

0:13:39respect or hopefully the people who respect you, which is starting to get into your colleagues.

0:13:45And that's where it really gets scary because these are people whose opinion you know is

0:13:49more honest and whose opinion you value in a way that is different than you would value

0:13:55your spouse.

0:13:56Not that I don't value my spouse's opinion, but it's a different kind of validation.

0:14:01Because when she says she likes what I'm doing, she's liking not just the app itself.

0:14:06It's in the context of all the work I've put into it, in the context of all the decisions we've jointly made about it, and so on.

0:14:13And so it's always a tricky thing.

0:14:22But I'm just going to encourage everybody to, you have to let go.

0:14:22to let go. You just have to understand that at some point you have to sort of let the

0:14:26bird fly free or whatever and just trust that you've made the right choices and hope that

0:14:31it goes well. That's kind of the scary point that I am now and I'm starting to send out

0:14:35beta testing and getting feedback and overall it's been positive, but it's just a scary

0:14:39point and I just wanted to voice that because I suspect many people feel that, that you

0:14:43just kind of have this timidness to show it to anybody, but ultimately that's probably

0:14:47going to be counterproductive. You just have to let go.

0:14:50Alright, that's it for today's show.

0:14:52As always, if you have questions, comments, concerns, I'm on Twitter @_DavidSmith.

0:14:56And otherwise, if you have a great weekend, happy coding, and I'll talk to you on Tuesday.