Developing Perspective

#117: Avoid, Defer, Remember.


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

00:00:04   news of note and iOS development, Apple and the like. I'm your host, David Smith. I'm

00:00:08   an independent iOS and Mac developer based in Herne, Virginia. This is show number 117

00:00:13   and today is Tuesday, April 2nd, 2013. Developing Perspective is never longer than 15 minutes,

00:00:18   so let's get going.

00:00:19   All right. So first, an explanation of why I was on the show last week. I was doing a

00:00:23   whole lot of different family stuff, Easter related, getting out of the household, it

00:00:27   It was painted, all kinds of things,

00:00:28   and it just didn't work to get it done.

00:00:30   So I'm sorry about that.

00:00:31   If you were looking forward to an episode,

00:00:33   hopefully I can make this one twice as good,

00:00:35   and that'll hopefully offset that a little bit.

00:00:37   So what I'm gonna be talking about today,

00:00:39   and it'll be one topic for the whole show,

00:00:41   it has a couple of different angles,

00:00:42   but is essentially, I've been working on feed wrangler.

00:00:46   I've been heading into the phase a little bit

00:00:48   of starting to work on performance,

00:00:50   and performance management, and kind of how to make things

00:00:53   go, work in a more performant way, I guess.

00:00:55   And so basically I was trying to think of a way

00:00:59   that how I go about this is almost kind of rote now.

00:01:02   Like I just kind of have a pattern and a phase I go into.

00:01:06   And I was trying to think about why I do it that way

00:01:08   and how I could kind of generalize that a little bit.

00:01:11   And that's kind of what I'm gonna talk about now.

00:01:13   And essentially what I've come up with is

00:01:15   performances really can only be solved or improved

00:01:19   in one of three ways.

00:01:20   And they're very related and there's a little bit

00:01:21   of overlap, but basically you can avoid work,

00:01:25   can defer work, and you can remember work. Those are really

00:01:30   the only three things you can do to make something faster. I'll

00:01:33   kind of walk through them in in turn and then also kind of some

00:01:36   thoughts I had that kind of come out of that. So the first one,

00:01:39   you can avoid work. This is all about actually improving the, I

00:01:45   guess you could call it the algorithmic complexity of what

00:01:47   you're doing. So this is if you come from a CS background, this

00:01:52   is one of those things that you can use is like the complexity

00:01:55   of the algorithm or the efficiency of the algorithm, those types of things where you

00:01:58   can actually avoid doing work. And if you're not, if you don't come up from a CS background,

00:02:03   I highly recommend going and looking at any of a dozen, just search for like sorting algorithms.

00:02:08   This is one of those funny things to remember from like, you know, sort of my early days

00:02:11   in CS at college, where you talk about how the same operation, if you have a list of

00:02:16   numbers and you want to sort them, you can do that sort in a variety of different ways.

00:02:21   And the difference in complexity and the amount of effort and like operations it takes to

00:02:25   do that can vary dramatically based on how you approach it.

00:02:29   You know, you can go from things like quicksort and mergesort, which are what they call logarithmic

00:02:33   complexity to things that, you know, I think there's sort of some sorting algorithms that

00:02:38   are like cubic, which if those terms don't make any sense, like I said, go look at a

00:02:42   sorting thing.

00:02:43   But basically, the way you solve a problem can make, have a dramatic impact on the amount

00:02:48   of time it takes or the resources it takes, probably more generally, it takes to do it.

00:02:54   And so the first thing you can do is kind of see are there things that I'm doing here

00:02:57   that I can avoid doing, that I can just not do, that I can improve my algorithm, my approach,

00:03:02   that I can kind of take a different thing to it and that would improve the performance

00:03:09   of my application.

00:03:10   And if you can, then that's awesome.

00:03:12   That's a great way to sort of like free, it's free, you know, in terms of you're not, all

00:03:17   All you're getting, it's like you're just changing

00:03:19   slightly how you do something,

00:03:21   and the result is sort of almost all outside.

00:03:24   The next area that you can do things is,

00:03:26   I said you can defer things.

00:03:28   And this is essentially ways of creating the appearance

00:03:32   of performance without necessarily changing

00:03:35   the amount of work you do.

00:03:37   So if you've gotten to a point that your algorithm,

00:03:39   your approach, the way you're tackling a problem

00:03:41   is as efficient as possible,

00:03:44   or as efficient as reasonably possible,

00:03:46   thing you can do is you can start deferring work. And this is mostly about optimizing

00:03:50   for the user's experience so that they have a perception of high speed interactivity,

00:03:57   whatever it is, that things are going quicker, but whereas they may actually not be the case.

00:04:01   Examples of that are, for example, on iOS is putting things into background threads

00:04:06   using Grand Central Dispatch, those types of approaches where the main thread, the thing

00:04:11   that the user is actually interacting with can be very performant. It can go do very

00:04:14   very quickly responsive, all those types of things.

00:04:17   But the app's actually doing a lot.

00:04:19   It's just doing it in different threads away from the user

00:04:23   so the user isn't aware of that work.

00:04:25   So this is an example of things where

00:04:27   you can take that operation and put it somewhere else

00:04:31   in a way that can use.

00:04:31   Say you're doing a big import.

00:04:33   You do that off the main thread.

00:04:34   You don't lock that up.

00:04:35   The user has a perception of performance,

00:04:37   even though that same amount of work is still getting done.

00:04:40   Similarly, this is something that I've

00:04:42   been working in a lot with Feed Wrangler,

00:04:44   is in most web applications you can't do very much

00:04:48   during the actual request.

00:04:49   If it's any kind of long-lived process,

00:04:52   you need to move it onto a background processor,

00:04:55   something that is gonna be kind of working in the background

00:04:58   and having the user interact with it in another way.

00:05:01   And that's something that I've recently been

00:05:02   getting into a lot with, you know,

00:05:04   I think right now I'm using Sidekick,

00:05:05   which is just a Rails backgrounding tool

00:05:07   that seems to be really, really awesome.

00:05:09   And what it allows you to do is you can say,

00:05:12   okay, I need to do this long operation,

00:05:14   I need to import from Google Reader,

00:05:16   I'm gonna kick that off in the background,

00:05:18   and then you can come back to the user and say,

00:05:19   hey, I started, hey, I'm updating,

00:05:22   oh, did some work, did some work, did some work.

00:05:24   And you can create the effect of appearance

00:05:28   of a lot of progress in a way that's much more useful

00:05:31   and interesting to a user than if you just

00:05:33   sort of had the request take longer,

00:05:36   had it take 60 seconds to complete.

00:05:39   Just not a good user experience.

00:05:40   can put it off, you can delay it. And then the thirdly, and

00:05:44   the third area that you can do is that you can remember work.

00:05:47   And this is caching. I mean, I'm just I'm kind of turning it into

00:05:51   you know, calling it, calling it in that name, because it's, you

00:05:55   know, it's fits well with the structure of the others. But

00:05:57   basically, it's just caching and caching is a very tricky

00:06:00   problem. But it's also very powerful. And caching is just

00:06:02   when you remember something you've done before, so that you

00:06:05   don't have to do it again. It's a different kind of avoiding

00:06:09   work because obviously you can avoid doing certain kinds of operations if that operation

00:06:14   is already, if you've already done it once, you can just not do it again if you remember

00:06:19   it. Now, caching is very complicated because you have to make sure that what you're doing

00:06:23   is the exact same work that you're trying to avoid. So it's similar but subtly different

00:06:31   could create all kinds of problems for you down the road.

00:06:33   And then on the flip side of that, too, is caching can take a lot of other resources.

00:06:39   You're not avoiding work.

00:06:40   So I was saying at the beginning when if you avoid work, it's sort of free.

00:06:44   It's not really coming at an additional cost, typically.

00:06:46   You know, if you just use a more efficient algorithm or those types of things, there's

00:06:49   usually not a lot of downside to that.

00:06:52   With something like caching, though, you can create all kinds of downsides in terms of

00:06:55   now you have to invalidate caches, you have to expire caches, you have to manage them.

00:06:59   They can take a lot of space, which can annoy users.

00:07:02   And so it's kind of a tricky thing to do.

00:07:04   But overall, caching typically is a big win.

00:07:06   It typically is something that lets

00:07:08   you have a lot of benefits in terms of performance,

00:07:12   because the time it takes to retrieve something

00:07:15   is almost always going to be faster than the time it

00:07:17   is to regenerate something, certainly

00:07:19   for the kind of objects that you'd be looking to cache.

00:07:21   And so that's kind of the three approaches

00:07:23   that you can take to improving the performance of something.

00:07:25   You can avoid it, you can defer it or delay it,

00:07:30   and you can remember it for later.

00:07:32   And in general, that's really all you can do.

00:07:37   And so when I find myself in a performance cycle,

00:07:40   when I'm finding myself stuck on something

00:07:42   that I want to be faster, that I'm working on a problem

00:07:45   and I'm like, you know, really, I want this to be more responsive.

00:07:47   I want this to be faster.

00:07:49   I want this to look better for the user.

00:07:50   That's really the three things that I do.

00:07:52   And I kind of work through them, generally speaking,

00:07:53   in that order, that I'll try and see,

00:07:57   is there a way that I can do this more efficiently?

00:07:59   And often there is.

00:08:00   Often there is, when I'm building something initially,

00:08:02   what I'm doing is just attacking it from the most--

00:08:06   I had a professor in college who always

00:08:07   used to call it the naive solution.

00:08:09   And the naive solution is usually the obvious one

00:08:12   that gets the result the most--

00:08:14   the result in the quickest in terms of your development time,

00:08:18   but not the quickest in terms of the actual computational time.

00:08:21   And so often I'll just build the naive solution,

00:08:23   and that's fine.

00:08:24   I'll build it, I'll deploy it, and then it

00:08:27   gives me a good starting point from which I can work.

00:08:29   And I'll say, hey, can I make this faster?

00:08:31   Am I doing stuff here in a way that's silly?

00:08:33   Am I iterating over something in ways

00:08:35   that I really don't need to break out of this loop?

00:08:37   Would that help this better?

00:08:38   Can I split up the work?

00:08:40   There's all kinds of things you can

00:08:41   do to make something faster.

00:08:43   And then once I've got to that point, then it's like, OK,

00:08:46   well, this is how long this is going

00:08:47   to take to do, no matter what.

00:08:49   That's what I'm saying.

00:08:50   This is as performant as can be.

00:08:52   Is there a way that I can do this in a way

00:08:53   that the user won't notice?

00:08:55   Can I defer this off of the user's attention

00:08:58   so that they don't have to worry about the time it's taking?

00:09:01   And I'll try to work that out.

00:09:02   Like I said, on iOS, almost always,

00:09:03   it's going to be taking long operations

00:09:06   and be moving them off the main thread,

00:09:08   and then just reporting results back to the main thread.

00:09:10   And that creates a tremendous boost

00:09:12   in terms of perceived performance,

00:09:13   even though the same amount of work is being done.

00:09:16   And then the last area is going to be just caching.

00:09:17   I'm going to say, OK, now that I've

00:09:20   done this whole big chunk of work once,

00:09:22   can I save it in such a way that I don't have to do it again? And

00:09:25   that can come into a variety of different ways. This doesn't

00:09:28   have to just be sort of something that's algorithmic. Of

00:09:31   course, this is saving network saving network requests, you

00:09:35   know, caching, you know, say in check the weather, I cache the

00:09:38   latest weather report that I get for a particular GPS location.

00:09:42   So that if you happen to ask for that same request again, 30

00:09:46   seconds later, I'm just going to give it back to you because the

00:09:49   weather hasn't changed in that last 30 seconds. And so you can

00:09:52   do things like that, that just overall will increase the

00:09:55   efficiency of your of your, of your system. It's also one thing

00:09:59   that I wanted to kind of have a slight tangent on. It seemed

00:10:03   off kind of interesting that those same three things apply, I

00:10:05   think more generally also, to the way we approach work and

00:10:09   work life. And by that, I mean, as I approach whatever it is,

00:10:13   sorry, you could say productivity or just work in

00:10:17   in general. If I start from an assumption that what I'm doing is worthwhile, interesting,

00:10:24   useful, and important, there's only three ways that I can do to improve my productivity.

00:10:29   I can either find ways to do what I do more efficiently. These are things that would improve

00:10:36   the ability of whatever it is that I'm doing. This is like try writing code in Xcode versus

00:10:44   in TextMate if you're doing iOS development.

00:10:46   You're going to be a lot more productive probably in Xcode

00:10:49   in terms of it does-- there's a lot of affordances and things

00:10:51   that improve the efficiency of that process.

00:10:53   You can defer work, which when I think of it in this way

00:10:55   is taking it off the main thread is delegating, is outsourcing,

00:10:59   is taking that work and having someone else do it.

00:11:01   So this is having someone else do your taxes,

00:11:02   having someone else do your help desk,

00:11:04   having someone else do your graphic design, your icon

00:11:06   design, having taken things where you can defer that work

00:11:09   away from yourself in a way that increases your productivity,

00:11:13   And then caching is an interesting thing when you try and apply it to yourself, because

00:11:17   that makes me think about trying to be good about things like code reuse, which is a classic

00:11:24   example of something like that, or even just kind of being mindful about how you work and

00:11:28   remembering the mistakes you've made before and being kind of mindful of that so that

00:11:34   you can avoid making the same mistake again.

00:11:36   That can be in a formal way if you like.

00:11:38   But generally for me, it's just something that I try and part of it, honestly, that's

00:11:41   why I do this show is that it helps me to think through the mistakes I've made in a

00:11:44   way that helps me avoid doing them in the future.

00:11:47   And so that's getting a little bit esoteric, but that's just kind of something that I was

00:11:50   thinking about as I was preparing this talk to talk about kind of how I do, how I go about

00:11:54   performance.

00:11:55   I think you can apply that same thing into a lot of different areas in your life.

00:11:58   And the result is pretty good.

00:12:00   Anyway, that's it for today's show.

00:12:02   As always, if you have questions, comments, concerns, or complaints, I'm on Twitter @_DavidSmith.

00:12:06   I'm on AppNet @DavidSmith.

00:12:07   You can email me, david@developingperspective.com.

00:12:09   Otherwise, you have a great week, happy coding, and I will talk to you later.