0:00:00Hello and welcome to Developing Perspective. Developing Perspective is a podcast discussing
0:00:04news of note and iOS development, Apple and the like. I'm your host, David Smith. I'm
0:00:08an independent iOS and Mac developer based in Herne, Virginia. This is show number 117
0:00:13and today is Tuesday, April 2nd, 2013. Developing Perspective is never longer than 15 minutes,
0:00:18so let's get going.
0:00:19All right. So first, an explanation of why I was on the show last week. I was doing a
0:00:23whole lot of different family stuff, Easter related, getting out of the household, it
0:00:27It was painted, all kinds of things,
0:00:28and it just didn't work to get it done.
0:00:30So I'm sorry about that.
0:00:31If you were looking forward to an episode,
0:00:33hopefully I can make this one twice as good,
0:00:35and that'll hopefully offset that a little bit.
0:00:37So what I'm gonna be talking about today,
0:00:39and it'll be one topic for the whole show,
0:00:41it has a couple of different angles,
0:00:42but is essentially, I've been working on feed wrangler.
0:00:46I've been heading into the phase a little bit
0:00:48of starting to work on performance,
0:00:50and performance management, and kind of how to make things
0:00:53go, work in a more performant way, I guess.
0:00:55And so basically I was trying to think of a way
0:00:59that how I go about this is almost kind of rote now.
0:01:02Like I just kind of have a pattern and a phase I go into.
0:01:06And I was trying to think about why I do it that way
0:01:08and how I could kind of generalize that a little bit.
0:01:11And that's kind of what I'm gonna talk about now.
0:01:13And essentially what I've come up with is
0:01:15performances really can only be solved or improved
0:01:19in one of three ways.
0:01:20And they're very related and there's a little bit
0:01:21of overlap, but basically you can avoid work,
0:01:25can defer work, and you can remember work. Those are really
0:01:30the only three things you can do to make something faster. I'll
0:01:33kind of walk through them in in turn and then also kind of some
0:01:36thoughts I had that kind of come out of that. So the first one,
0:01:39you can avoid work. This is all about actually improving the, I
0:01:45guess you could call it the algorithmic complexity of what
0:01:47you're doing. So this is if you come from a CS background, this
0:01:52is one of those things that you can use is like the complexity
0:01:55of the algorithm or the efficiency of the algorithm, those types of things where you
0:01:58can actually avoid doing work. And if you're not, if you don't come up from a CS background,
0:02:03I highly recommend going and looking at any of a dozen, just search for like sorting algorithms.
0:02:08This is one of those funny things to remember from like, you know, sort of my early days
0:02:11in CS at college, where you talk about how the same operation, if you have a list of
0:02:16numbers and you want to sort them, you can do that sort in a variety of different ways.
0:02:21And the difference in complexity and the amount of effort and like operations it takes to
0:02:25do that can vary dramatically based on how you approach it.
0:02:29You know, you can go from things like quicksort and mergesort, which are what they call logarithmic
0:02:33complexity to things that, you know, I think there's sort of some sorting algorithms that
0:02:38are like cubic, which if those terms don't make any sense, like I said, go look at a
0:02:42sorting thing.
0:02:43But basically, the way you solve a problem can make, have a dramatic impact on the amount
0:02:48of time it takes or the resources it takes, probably more generally, it takes to do it.
0:02:54And so the first thing you can do is kind of see are there things that I'm doing here
0:02:57that I can avoid doing, that I can just not do, that I can improve my algorithm, my approach,
0:03:02that I can kind of take a different thing to it and that would improve the performance
0:03:09of my application.
0:03:10And if you can, then that's awesome.
0:03:12That's a great way to sort of like free, it's free, you know, in terms of you're not, all
0:03:17All you're getting, it's like you're just changing
0:03:19slightly how you do something,
0:03:21and the result is sort of almost all outside.
0:03:24The next area that you can do things is,
0:03:26I said you can defer things.
0:03:28And this is essentially ways of creating the appearance
0:03:32of performance without necessarily changing
0:03:35the amount of work you do.
0:03:37So if you've gotten to a point that your algorithm,
0:03:39your approach, the way you're tackling a problem
0:03:41is as efficient as possible,
0:03:44or as efficient as reasonably possible,
0:03:46thing you can do is you can start deferring work. And this is mostly about optimizing
0:03:50for the user's experience so that they have a perception of high speed interactivity,
0:03:57whatever it is, that things are going quicker, but whereas they may actually not be the case.
0:04:01Examples of that are, for example, on iOS is putting things into background threads
0:04:06using Grand Central Dispatch, those types of approaches where the main thread, the thing
0:04:11that the user is actually interacting with can be very performant. It can go do very
0:04:14very quickly responsive, all those types of things.
0:04:17But the app's actually doing a lot.
0:04:19It's just doing it in different threads away from the user
0:04:23so the user isn't aware of that work.
0:04:25So this is an example of things where
0:04:27you can take that operation and put it somewhere else
0:04:31in a way that can use.
0:04:31Say you're doing a big import.
0:04:33You do that off the main thread.
0:04:34You don't lock that up.
0:04:35The user has a perception of performance,
0:04:37even though that same amount of work is still getting done.
0:04:40Similarly, this is something that I've
0:04:42been working in a lot with Feed Wrangler,
0:04:44is in most web applications you can't do very much
0:04:48during the actual request.
0:04:49If it's any kind of long-lived process,
0:04:52you need to move it onto a background processor,
0:04:55something that is gonna be kind of working in the background
0:04:58and having the user interact with it in another way.
0:05:01And that's something that I've recently been
0:05:02getting into a lot with, you know,
0:05:04I think right now I'm using Sidekick,
0:05:05which is just a Rails backgrounding tool
0:05:07that seems to be really, really awesome.
0:05:09And what it allows you to do is you can say,
0:05:12okay, I need to do this long operation,
0:05:14I need to import from Google Reader,
0:05:16I'm gonna kick that off in the background,
0:05:18and then you can come back to the user and say,
0:05:19hey, I started, hey, I'm updating,
0:05:22oh, did some work, did some work, did some work.
0:05:24And you can create the effect of appearance
0:05:28of a lot of progress in a way that's much more useful
0:05:31and interesting to a user than if you just
0:05:33sort of had the request take longer,
0:05:36had it take 60 seconds to complete.
0:05:39Just not a good user experience.
0:05:40can put it off, you can delay it. And then the thirdly, and
0:05:44the third area that you can do is that you can remember work.
0:05:47And this is caching. I mean, I'm just I'm kind of turning it into
0:05:51you know, calling it, calling it in that name, because it's, you
0:05:55know, it's fits well with the structure of the others. But
0:05:57basically, it's just caching and caching is a very tricky
0:06:00problem. But it's also very powerful. And caching is just
0:06:02when you remember something you've done before, so that you
0:06:05don't have to do it again. It's a different kind of avoiding
0:06:09work because obviously you can avoid doing certain kinds of operations if that operation
0:06:14is already, if you've already done it once, you can just not do it again if you remember
0:06:19it. Now, caching is very complicated because you have to make sure that what you're doing
0:06:23is the exact same work that you're trying to avoid. So it's similar but subtly different
0:06:31could create all kinds of problems for you down the road.
0:06:33And then on the flip side of that, too, is caching can take a lot of other resources.
0:06:39You're not avoiding work.
0:06:40So I was saying at the beginning when if you avoid work, it's sort of free.
0:06:44It's not really coming at an additional cost, typically.
0:06:46You know, if you just use a more efficient algorithm or those types of things, there's
0:06:49usually not a lot of downside to that.
0:06:52With something like caching, though, you can create all kinds of downsides in terms of
0:06:55now you have to invalidate caches, you have to expire caches, you have to manage them.
0:06:59They can take a lot of space, which can annoy users.
0:07:02And so it's kind of a tricky thing to do.
0:07:04But overall, caching typically is a big win.
0:07:06It typically is something that lets
0:07:08you have a lot of benefits in terms of performance,
0:07:12because the time it takes to retrieve something
0:07:15is almost always going to be faster than the time it
0:07:17is to regenerate something, certainly
0:07:19for the kind of objects that you'd be looking to cache.
0:07:21And so that's kind of the three approaches
0:07:23that you can take to improving the performance of something.
0:07:25You can avoid it, you can defer it or delay it,
0:07:30and you can remember it for later.
0:07:32And in general, that's really all you can do.
0:07:37And so when I find myself in a performance cycle,
0:07:40when I'm finding myself stuck on something
0:07:42that I want to be faster, that I'm working on a problem
0:07:45and I'm like, you know, really, I want this to be more responsive.
0:07:47I want this to be faster.
0:07:49I want this to look better for the user.
0:07:50That's really the three things that I do.
0:07:52And I kind of work through them, generally speaking,
0:07:53in that order, that I'll try and see,
0:07:57is there a way that I can do this more efficiently?
0:07:59And often there is.
0:08:00Often there is, when I'm building something initially,
0:08:02what I'm doing is just attacking it from the most--
0:08:06I had a professor in college who always
0:08:07used to call it the naive solution.
0:08:09And the naive solution is usually the obvious one
0:08:12that gets the result the most--
0:08:14the result in the quickest in terms of your development time,
0:08:18but not the quickest in terms of the actual computational time.
0:08:21And so often I'll just build the naive solution,
0:08:23and that's fine.
0:08:24I'll build it, I'll deploy it, and then it
0:08:27gives me a good starting point from which I can work.
0:08:29And I'll say, hey, can I make this faster?
0:08:31Am I doing stuff here in a way that's silly?
0:08:33Am I iterating over something in ways
0:08:35that I really don't need to break out of this loop?
0:08:37Would that help this better?
0:08:38Can I split up the work?
0:08:40There's all kinds of things you can
0:08:41do to make something faster.
0:08:43And then once I've got to that point, then it's like, OK,
0:08:46well, this is how long this is going
0:08:47to take to do, no matter what.
0:08:49That's what I'm saying.
0:08:50This is as performant as can be.
0:08:52Is there a way that I can do this in a way
0:08:53that the user won't notice?
0:08:55Can I defer this off of the user's attention
0:08:58so that they don't have to worry about the time it's taking?
0:09:01And I'll try to work that out.
0:09:02Like I said, on iOS, almost always,
0:09:03it's going to be taking long operations
0:09:06and be moving them off the main thread,
0:09:08and then just reporting results back to the main thread.
0:09:10And that creates a tremendous boost
0:09:12in terms of perceived performance,
0:09:13even though the same amount of work is being done.
0:09:16And then the last area is going to be just caching.
0:09:17I'm going to say, OK, now that I've
0:09:20done this whole big chunk of work once,
0:09:22can I save it in such a way that I don't have to do it again? And
0:09:25that can come into a variety of different ways. This doesn't
0:09:28have to just be sort of something that's algorithmic. Of
0:09:31course, this is saving network saving network requests, you
0:09:35know, caching, you know, say in check the weather, I cache the
0:09:38latest weather report that I get for a particular GPS location.
0:09:42So that if you happen to ask for that same request again, 30
0:09:46seconds later, I'm just going to give it back to you because the
0:09:49weather hasn't changed in that last 30 seconds. And so you can
0:09:52do things like that, that just overall will increase the
0:09:55efficiency of your of your, of your system. It's also one thing
0:09:59that I wanted to kind of have a slight tangent on. It seemed
0:10:03off kind of interesting that those same three things apply, I
0:10:05think more generally also, to the way we approach work and
0:10:09work life. And by that, I mean, as I approach whatever it is,
0:10:13sorry, you could say productivity or just work in
0:10:17in general. If I start from an assumption that what I'm doing is worthwhile, interesting,
0:10:24useful, and important, there's only three ways that I can do to improve my productivity.
0:10:29I can either find ways to do what I do more efficiently. These are things that would improve
0:10:36the ability of whatever it is that I'm doing. This is like try writing code in Xcode versus
0:10:44in TextMate if you're doing iOS development.
0:10:46You're going to be a lot more productive probably in Xcode
0:10:49in terms of it does-- there's a lot of affordances and things
0:10:51that improve the efficiency of that process.
0:10:53You can defer work, which when I think of it in this way
0:10:55is taking it off the main thread is delegating, is outsourcing,
0:10:59is taking that work and having someone else do it.
0:11:01So this is having someone else do your taxes,
0:11:02having someone else do your help desk,
0:11:04having someone else do your graphic design, your icon
0:11:06design, having taken things where you can defer that work
0:11:09away from yourself in a way that increases your productivity,
0:11:13And then caching is an interesting thing when you try and apply it to yourself, because
0:11:17that makes me think about trying to be good about things like code reuse, which is a classic
0:11:24example of something like that, or even just kind of being mindful about how you work and
0:11:28remembering the mistakes you've made before and being kind of mindful of that so that
0:11:34you can avoid making the same mistake again.
0:11:36That can be in a formal way if you like.
0:11:38But generally for me, it's just something that I try and part of it, honestly, that's
0:11:41why I do this show is that it helps me to think through the mistakes I've made in a
0:11:44way that helps me avoid doing them in the future.
0:11:47And so that's getting a little bit esoteric, but that's just kind of something that I was
0:11:50thinking about as I was preparing this talk to talk about kind of how I do, how I go about
0:11:54performance.
0:11:55I think you can apply that same thing into a lot of different areas in your life.
0:11:58And the result is pretty good.
0:12:00Anyway, that's it for today's show.
0:12:02As always, if you have questions, comments, concerns, or complaints, I'm on Twitter @_DavidSmith.
0:12:06I'm on AppNet @DavidSmith.
0:12:07You can email me, david@developingperspective.com.
0:12:09Otherwise, you have a great week, happy coding, and I will talk to you later.