PodSearch

Developing Perspective

#83: Performance and Letting Go.

 

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

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

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

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

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

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

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

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

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

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

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

00:00:45 ◼   ► I think it's basically ready.

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

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

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

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

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

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

00:01:01 ◼   ► that you'll do towards the end of actual app construction.

00:01:04 ◼   ► And that's performance improvements and performance testing.

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

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

00:01:14 ◼   ► talking about how I go about that and what that looks like.

00:01:17 ◼   ► So performance is most often just sort of--

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

00:01:25 ◼   ► And quickly is ideally defined as imperceptibly fast.

00:01:30 ◼   ► So the goal would be that ideally the user never really is aware

00:01:34 ◼   ► that any operation is taking time to perform.

00:01:36 ◼   ► It just happens.

00:01:37 ◼   ► It's instantaneous as far as possible.

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

00:01:46 ◼   ► that illusion or performance enhancing techniques

00:01:51 ◼   ► and approaches that you can do to make that the actual case.

00:01:54 ◼   ► And so what I've done essentially is,

00:01:59 ◼   ► as I've talked about, I've built the app,

00:02:01 ◼   ► I prototyped it, I worked on the fun,

00:02:03 ◼   ► sort of scaling on the feature set,

00:02:05 ◼   ► understand exactly what it is I'm going to build,

00:02:07 ◼   ► and then I started this process of refinement.

00:02:09 ◼   ► And you kind of want to think about this as,

00:02:12 ◼   ► if you've ever done carpentry with a sandpaper, right,

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

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

00:02:19 ◼   ► is take some sandpaper and you're going to

00:02:22 ◼   ► be starting to smooth it off.

00:02:23 ◼   ► And your goal is to make it as silky smooth as possible.

00:02:26 ◼   ► And the way you, if you've ever done any carpentry,

00:02:29 ◼   ► the way that you go about doing that is you start off

00:02:31 ◼   ► with a really rough sandpaper.

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

00:02:37 ◼   ► at a time, you're kind of really,

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

00:02:42 ◼   ► you're just kind of going at it.

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

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

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

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

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

00:03:08 ◼   ► to the user.

00:03:09 ◼   ► I want to do those first.

00:03:10 ◼   ► and I want to get the groundwork of that going.

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

00:03:17 ◼   ► and I'll be like, "Man, that's slow,"

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

00:03:24 ◼   ► or some focused area of the app.

00:03:26 ◼   ► The number one rule of performance improvement is measurement.

00:03:29 ◼   ► If you don't measure what you're doing,

00:03:31 ◼   ► you're probably going to drive yourself crazy

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

00:03:36 ◼   ► By measurement, what I typically mean is either in instruments,

00:03:39 ◼   ► instruments, looking at whatever memory performance, frames

00:03:42 ◼   ► per second, the time profilers, stack trace,

00:03:46 ◼   ► like those types of things.

00:03:48 ◼   ► Or even just something as simple as grabbing the time

00:03:51 ◼   ► before and after an operation completes

00:03:53 ◼   ► and NS logging that to the console.

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

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

00:04:01 ◼   ► making are actually doing anything.

00:04:03 ◼   ► And you'll just end up chasing your tail.

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

00:04:07 ◼   ► change, I think that helped.

00:04:09 ◼   ► But maybe I'll do this other thing, too.

00:04:10 ◼   ► I may be able to do this other thing.

00:04:12 ◼   ► And then the second rule is that you,

00:04:15 ◼   ► in addition to measuring everything,

00:04:17 ◼   ► you want to only ever change one thing at a time.

00:04:22 ◼   ► And these two things go together,

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

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

00:04:30 ◼   ► Or worse, you make lots of changes at once

00:04:32 ◼   ► and then kind of run through the app.

00:04:34 ◼   ► It's almost impossible at that point

00:04:36 ◼   ► to get a good sense of actually what's happening.

00:04:39 ◼   ► And you're just going to drive yourself crazy.

00:04:41 ◼   ► So for a performance measurement, like I said,

00:04:43 ◼   ► I'll use a lot of instruments for a lot of it.

00:04:46 ◼   ► And then the second thing that I do

00:04:48 ◼   ► is just these print lines, and I'll

00:04:49 ◼   ► have those all over the place.

00:04:51 ◼   ► And so the first thing that I tackle--

00:04:53 ◼   ► and this is probably, honestly, in my opinion,

00:04:56 ◼   ► the most important thing that you

00:04:59 ◼   ► can do for performance testing and improvement

00:05:03 ◼   ► is that you want to focus on launch time.

00:05:05 ◼   ► I think it's probably the most important bit of performance.

00:05:10 ◼   ► I guess to me it's a bit strong.

00:05:12 ◼   ► But it is certainly one of the most important areas

00:05:15 ◼   ► of performance in your application

00:05:16 ◼   ► because it's the user's first impression.

00:05:18 ◼   ► And it's an impression that they're

00:05:20 ◼   ► going to be making over and over and over again.

00:05:22 ◼   ► Now, I know the app goes into a background state

00:05:24 ◼   ► and may not actually be relaunched a lot.

00:05:26 ◼   ► But I want that app's launch screen

00:05:29 ◼   ► to disappear as quickly as possible.

00:05:31 ◼   ► And the reason for that is that is, by definition,

00:05:34 ◼   ► time that the user is wasting.

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

00:05:39 ◼   ► or it can be faster at downloading stuff, faster

00:05:42 ◼   ► at this, faster at that.

00:05:43 ◼   ► But often those things are happening

00:05:45 ◼   ► while the user can do something else

00:05:47 ◼   ► or is looking at something else.

00:05:49 ◼   ► But with launch time, that's it.

00:05:51 ◼   ► All they can do is wait.

00:05:52 ◼   ► They can't do anything else while that happens.

00:05:54 ◼   ► So you want to make that as fast as possible.

00:05:57 ◼   ► And the first rule of making your launch time fast

00:06:00 ◼   ► is doing almost nothing on the main thread

00:06:04 ◼   ► from application did finish launching to view did load,

00:06:08 ◼   ► view did appear.

00:06:09 ◼   ► And hopefully those terms make sense

00:06:10 ◼   ► if you're an app developer.

00:06:11 ◼   ► But basically from when your app starts

00:06:13 ◼   ► until you have shown things and so you finish showing something

00:06:16 ◼   ► on the screen, whatever that first thing is,

00:06:18 ◼   ► you want to do as little as possible on the main thread.

00:06:21 ◼   ► You want to put off as much as possible.

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

00:06:26 ◼   ► And that typically works out pretty well

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

00:06:31 ◼   ► and GCD queues, or just doing things where you can say,

00:06:35 ◼   ► dispatch async on the main thread.

00:06:38 ◼   ► And you're pushing these things off.

00:06:40 ◼   ► So if you need them to happen up front,

00:06:42 ◼   ► you need to do these things right away, do them early,

00:06:45 ◼   ► but don't do them until you've started

00:06:47 ◼   ► showing something to the user.

00:06:50 ◼   ► It's just really important that you don't do that.

00:06:53 ◼   ► And then the second thing that I do

00:06:55 ◼   ► is you're trying to optimize that first view stack

00:06:59 ◼   ► that you're going to show the user.

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

00:07:05 ◼   ► and the data you load and the data you need

00:07:07 ◼   ► is all an important part of that.

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

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

00:07:18 ◼   ► down in my naive, basic, simple solution.

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

00:07:24 ◼   ► seconds.

00:07:25 ◼   ► And I got it down to about 0.3 seconds

00:07:29 ◼   ► by a lot of these things.

00:07:31 ◼   ► So all those different things in aggregate.

00:07:32 ◼   ► And then I was pleasantly surprised

00:07:34 ◼   ► that when I got my iPhone 4-- or my iPhone 5,

00:07:38 ◼   ► my launch time is now down to 0.1 seconds, which

00:07:43 ◼   ► if you think about how short of a time that is,

00:07:46 ◼   ► it's basically instantaneous.

00:07:48 ◼   ► And it looks basically like the app launches immediately,

00:07:52 ◼   ► which I'm really, really proud of.

00:07:54 ◼   ► And I really like that part of it.

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

00:07:58 ◼   ► It's like, let me quit the app in the multitasking

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

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

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

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

00:08:25 ◼   ► or a banner or a logo.

00:08:27 ◼   ► And a big part of that is that really helps with the perceived

00:08:32 ◼   ► load time of the application, because that

00:08:35 ◼   ► will show instantaneously.

00:08:36 ◼   ► And so it shows that, and then it shows your app.

00:08:39 ◼   ► And so if those two things are the same,

00:08:42 ◼   ► it almost looks like your app's loaded immediately.

00:08:45 ◼   ► And just that extra 0.1, 0.2, 0.3 of a second

00:08:48 ◼   ► that it took to actually load is just almost

00:08:51 ◼   ► like you can make it look like an animation,

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

00:08:58 ◼   ► actually were doing stuff in the background.

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

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

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

00:09:13 ◼   ► the way that I was saving files to disk, saving the way that the data structures that I was

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

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

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

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

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

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

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

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

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

00:09:58 ◼   ► they're making certain assumptions.

00:09:59 ◼   ► They're all making different adjustments and things,

00:10:01 ◼   ► how they're going to handle different encodings,

00:10:03 ◼   ► how they're going to handle different data structures.

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

00:10:09 ◼   ► not just which one's fastest based on benchmarks.

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

00:10:14 ◼   ► I think it's fast. It's snappy.

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

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

00:10:25 ◼   ► I just gave up.

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

00:10:29 ◼   ► And increasing-- the 4 is probably my performance baseline.

00:10:33 ◼   ► And it is pretty good.

00:10:35 ◼   ► It's visually smooth, but not as smooth as possible.

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

00:10:41 ◼   ► But it's an important thing for performance.

00:10:43 ◼   ► You don't want to go crazy and just constantly--

00:10:45 ◼   ► Could we go down this rabbit hole?

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

00:10:50 ◼   ► And I think, like the app, I'm really

00:10:52 ◼   ► proud of the performance of it just across the board.

00:10:55 ◼   ► And so that brings me to the next thing.

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

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

00:11:02 ◼   ► is going to launch hopefully on October 17,

00:11:06 ◼   ► which is in about 2 and 1/2 weeks-ish.

00:11:08 ◼   ► It's about three weeks from yesterday.

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

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

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

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

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

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

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

00:11:39 ◼   ► You just got to account for that.

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

00:11:46 ◼   ► and I find a bug, I find a problem, a beta tester,

00:11:51 ◼   ► a previewer, someone in the press finds some bug

00:11:55 ◼   ► that I want out, I have an opportunity to resubmit

00:11:57 ◼   ► and have that approved, hopefully, by the time

00:12:00 ◼   ► that I'm aiming to launch.

00:12:02 ◼   ► I'm picking a day specifically, so I can hopefully

00:12:04 ◼   ► coordinate some marketing, some press, reaching out

00:12:06 ◼   ► to my friends and colleagues and people to try

00:12:07 ◼   ► I find building some buzz and promotion around it,

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

00:12:13 ◼   ► rather than just like, it'll launch at some point

00:12:15 ◼   ► whenever it gets approved.

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

00:12:20 ◼   ► Hopefully that ends up working out.

00:12:22 ◼   ► Like I said, I'm submitting now.

00:12:24 ◼   ► That's about three weeks.

00:12:25 ◼   ► It should hopefully be OK in terms

00:12:27 ◼   ► of getting that through App Review by then.

00:12:29 ◼   ► But you just never know.

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

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

00:12:36 ◼   ► narrowing in on finally being able to ship this thing.

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

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

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

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

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

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

00:13:16 ◼   ► to critique it, to say what they think about it.

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

00:13:24 ◼   ► know.

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

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

00:13:35 ◼   ► And then you start to get into the scary part where you start to get into the people you

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

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

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

00:13:55 ◼   ► your spouse.

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

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

00:14:06 ◼   ► It'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.

00:14:13 ◼   ► And so it's always a tricky thing.

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

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

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

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

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

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

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

00:14:47 ◼   ► going to be counterproductive. You just have to let go.

00:14:50 ◼   ► Alright, that's it for today's show.

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

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