One of the conditions most feared by creatives in any field, from art to entrepreneurship, is burnout. According to Smith, Segal, and Segal, burnout is "a state of emotional, mental, and physical exhaustion caused by excessive and prolonged stress." Stress, of course, comes in many forms, from overbearing bosses to financial worry to an unstable spousal relationship. For business and creative types, though, sometimes the greatest stress comes from within: the demand to always do better, do more, work faster and harder. This type of endogenous stress, applied over a long enough time period, will result in burnout even in the presence of ideal external circumstances. When endogenous stress does result in burnout, getting out of it can be tremendously difficult.
There are two phases to escaping burnout, particularly of the self-imposed variety, and the order in which they are applied determines their effectiveness.
Phase One: Stop Identifying with the Work
When you're engaged deeply in any creative pursuit, there is a tendency for you to begin identifying with the thing you're making. It's your product, your book, your business, and just like a literal child, it's easy to see it as a little part of yourself. More importantly, every time you make a decision that shapes your workpiece, you're reinforcing pathways in your brain, making what's in your head echo into the physical world. You could even say that that's all creatives do: they manifest their visions by gradually bending matter and information to match what appears in their head. One thousand tiny decisions reinforce the similarity between the creative loci in your mind and the product in front of you. So it's no wonder you wind up feeling close to it.
The trouble occurs when burnout sets in and you switch gears from creation to criticism. This means that you start seeing just the flaws of the thing you're building: the rough edges, the shortcuts, the missing pieces. And then, because you identify so closely with this thing, you project its flaws back onto yourself, perhaps to the point of feeling completely worthless. One way or another, once you start hating what you do, it's only a matter of time till you hate yourself for doing it.
What's the solution? Somehow, you have to separate yourself from what you're making, recognizing that you are more than it, and better than the worst parts of it. That means taking a break. Maybe it's as easy as strolling to the corner for a cup of coffee to regain focus on the bigger things, but genuine cases of burnout take way more than that. You can start by taking a long weekend to unplug, severing all contact with whatever is ultimately responsible for your stress and catching up on reading, baking, or other leisurely activities. Most people who are prone to burnout never really disconnect themselves, feeling that they're being irresponsible by taking time purely for themselves. In fact, the advice above will be anathema to entrepreneurs early in their careers, who reason that the only way to get ahead is to go full-bore 24/7. Those who have been around the block and grappled with burnout know the folly in this kind of thinking, but it's almost impossible to talk someone out of overworking themselves when they haven't witnessed the inevitable fallout.
If you take care to avoid external stressors, and you can silence the internal voices chastising you for being lazy, you will eventually come to a place where you no longer identify so closely with the product that you feel exhausted when contemplating it. Then, you're ready for the second phase.
Phase Two: Delight in the Goodness of What you Do
There's a good chance, if you've taken at least a few steps toward crossing the chasm between "having good taste" and "making good things", that taking a break will grant you a new, positive outlook on the thing you've grown to dread. Perhaps you'll notice a particularly well-architected module, or an elegant stroke or bit of chiaroscuro, or you'll delight in a passage of dialogue between your protagonist and deuteragonist. It's important to take these things for what they are: powerful affirmations that what you're doing is both good and worthwhile. After all, you have taste and you think it's pretty good, so who's to say you're wrong?
It's crucial as you move through this phase not to fall back into identifying with the work. This continues to apply whether you feel great or poorly about it. The reason the phases have to happen in this order (separate, then contemplate objectively) is that burnout is a feedback loop when you identify with the product: the product is never perfect, so there's something wrong with you, so you spend more time on self-judgment and self-pity than the product, so you grow cynical toward the product, so you notice even more ways in which it falls short, so you feel even more inadequate... The point is to get back on an even keel, so even when you feel positively toward your work--even when you do and should feel proud of it--you can't get so close to it that you anchor your self-worth to it, because nothing we make is perfect.
In conclusion, sometimes burnout can be caused by exterior conditions. Hopefully you find yourself in a position to avoid the most grievous types of external stressors, but none of us can ever get all the way outside our own heads. And that's where some of the harshest criticism and toxic demotivation lies sometimes. Burnout caused by being overly self-critical and overly attached to what we're making is a real risk, and in order to defeat it, we first have to separate ourselves from the product far enough to see that we should care about more than just the product. And realizing that, we free ourselves to take the good with the bad, and get back to the noble act of creation.
From the time I started using email (around 1998) until a few months ago, the amount of email I received daily increased from a trickle to an uncontrollable torrent. Today, however, I monitor a total of six email accounts from a single interface, and I'm able to do so with very little effort and none of the sense of overwhelm that used to be common. My approach borrows from popular philosophies like GTD and Inbox Zero, but it's not a complete implementation of any of them. I wanted to write it down in case anyone is looking for a pragmatic way to get the email flood under control.
The Front Line
I get almost no outright spam. My professional accounts arrive from my own mail server, which runs SpamAssassin, and my personal accounts are filtered by Gmail. Before I had these aggressive front-line measures in place, I spent an unfortunate amount of time manually filtering and deleting spam. Life is too short for that kind of crap, so if you still get spam, look into how you can insert a more effective filter to keep it away.
Removing Needless Distraction
There is a class of email that is vastly more insidious than outright spam. It includes newsletters, mailing list digests, marketing messages from retailers, and product updates from online services. These messages are dangerous because they are targeted. You asked for them at some point (or at least didn't opt-out). They're often addressed to you personally (via a mail merge program, of course). And they're almost certainly not valuable.
If you actually care about reading the latest activity on your Google Groups or Quora, or you care about those sales at Fab or Gilt, or you need that coupon for Express or Victoria's Secret, that's fine. But I doubt you need all of them. I realized I didn't need any of them, but I was getting several per day anyway. It's easy to pull the trigger and give someone your email address on the pretext of them sending you "valuable messages," but they do add up, and they do take time to process (especially if you enjoy "retail therapy").
You can undo all the damage by clicking the "Unsubscribe Now" link in the email footer. Doing this religiously over the course of a couple of weeks drastically decreased my volume of incoming mail.
Making Real-Time Notifications More Ephemeral
Unsubscribing doesn't mean you have to disconnect yourself entirely. I used to receive email whenever anyone mentioned me on Twitter or Facebook. Now, I use the push notification features of their respective iPhone apps to stay alert. If I don't want to be distracted, I put my phone face-down and don't touch it for a few hours. The notifications accumulate on the home screen, and if I don't see anything interesting, they're gone with a swipe.
In this way, I'm able to reduce the permanence of these urgent but often trivial interactions. They don't stay in my inbox distracting me and needing cleaning; they just come and go. If you need to keep tabs on a less-chatty social network like LinkedIn, put a recurring event on your calendar to process all of the notifications in one shot instead of being distracted daily.
The inbox is sacred. The inbox is my collection of things that need to get done soon.
If I receive a message that I cannot act on in the next 24 hours, it gets turned into an event on my calendar, and I handle it when that date rolls around. If it doesn't need to be acted on at all, but might be useful for reference, it gets tagged and archived. If it is not actionable and I can convince myself I can look up the information it contains when I need it (which is probably never), it gets deleted outright. Not archived, deleted.
The inbox is sacred. The inbox contains only the things I need immediate access to.
Getting to this point is one of the most challenging parts of instituting sane email practices. If you haven't kept your inbox pared down, it likely has years of miscellaneous stuff you don't want to part with, homogeneously blended with all kinds of stuff that is worthless. You stare at this several times per day, and it's easy to become numb to its distracting and stress-inducing influence.
The inbox is sacred. The inbox is not a junk drawer.
The answer is the DMZ (a term borrowed from the military, meaning "demilitarized zone"). Create a tag or folder named DMZ, and move everything currently in your inbox into it. Odds are good that you'll never need to look in there again, but it's still accessible to your search feature if you need to look up a license key, password, or receipt. From this point forward, you can try to use a more strict tagging scheme to improve how quickly you can look things up. I personally use very broad tags (Work, Read Later, etc.) and rely on search almost exclusively.
Getting down to business
If you do everything I describe above, you will have a perfectly timely and relevant inbox, and the things arriving in it will have a much higher probability of being things you actually care about. My email has once again become a tool to improve my productivity by collecting the information I need and presenting a concise list of what needs my attention. If your email is out of control, try one or two of these tips to make it your ally again.
I recently opined on Twitter that the CMTimeMakeWithSeconds function (part of the Core Media framework in iOS and Mac OS X) behaves in very odd ways. This post is my attempt to explain the purpose of the CMTime structure, and how to work with the sometimes-confusing functions used to create and manipulate time objects.
A precise perspective on time
Most people never need to think very precisely about time. To take an extreme case, maybe you're an Olympic runner who cares about a difference of milliseconds between your speed and the world record in the 100m dash. That's about as far as it goes. When it comes to timed media, however, we often care about very short increments of time (tens of microseconds) and sometimes very long durations (days or weeks).
Suppose we want to precisely specify a moment in a movie file, like 35:06. A naïve approach would be to represent time as some double-precision floating-point quantity, like this: NSTimeInterval t = 2106.0;. This is actually fine for most uses, but it breaks down when we care about very long stretches of time divided up into very small slices. Without going into the mechanics of floating-point formats, such a double can hold roughly 16 (decimal) significant digits in 8 bytes (On all of the platforms I currently care about, sizeof(NSTimeInterval) == sizeof(Float64) == sizeof(double) == 8).
Floating-point numbers suffer one big problem: repeated operations (addition, multiplication, etc.) cause the accumulation of imprecision which can result in noticeable divergences after a long period of time, potentially causing errors in synchronizing multiple media streams.
As a quick example, summing up one million terms of 0.000001 results in a value of about 1.0000000000079181. The error is caused by the fact that 1e-6 cannot be exactly represented in the floating-point format we use, so we instead use a binary approximation that differs in its less-significant bits. This error is not that big, but if you're running an HTTP streaming server, you might be accumulating this imprecision several thousand times per second for an indefinite period of time.
This motivates us to find a way to represent time more precisely, by doing away with floating-point representations and their inherent imprecision (to say nothing of their hard-coded rounding behaviors).
Time as a rational number
There have been plenty of data structures used by Apple to represent time on the Mac and iOS platforms. With the introduction of iOS 4 and Mac OS X 10.7, a couple more were added: CMTime and CMTimeRange. Once you understand the former, the latter is pretty self-explanatory, so I won't spend any time discussing it here.
CMTime is really nothing more than a C struct with four members. It looks like this:
The remainder of this section will focus on value and timescale, but flags can take on some important values that will also merit a mention later. Various values of flags allow us to indicate that a timestamp is postive or negative infinity, or if it has been rounded as a result of some intermediate calculation. In this way, the struct is much more expressive than a single floating-point quantity could ever be, and this has numerous advantages.
Let us consider how time is actually expressed by the CMTime struct. It's very important to realize that value and timescale are both stored as integers: 64 bits and 32 bits respectively. It should be obvious from the previous discussion, but the reason value is stored as an integral value is to avoid the errors of the type we saw in the floating-point example. Also, by allocating an entire 64 bits to the numerator, we can represent 9 billion billion distinct positive values, up to 19 decimal digits, with no ambiguity, for each possible timescale value.
And what of the timescale value? It represents the number of "slices" each second is divided into. This matters because the precision of the CMTime object as a whole is limited by this quantity. For example, if timescale is 1, no timestamp smaller than 1 second can be represented by the object, and timestamps go in increments of one second. Similarly, if timescale is 1000, each second is subdivided into 1000 pieces, and the value member represents the number of milliseconds we want to signify.
How do you choose a sensible timescale to make sure you don't get truncated? Apple recommends a timescale of 600 for video, with the explanation that 600 is a multiple of the common video framerates (24, 25, and 30 FPS). You might want to crank this up to 60,000 or higher if you need sample-exact indexing on audio files. What's nice about those 64 bits in value is that you can still represent up to 5.8 million years in increments of 1/60,000th of a second unambiguously in this way.
The number of seconds represented by a timestamp is simply t.value / t.timescale. You can use the CMTimeGetSeconds function to easily transform a CMTime into a Float64 in a way that maintains as much precision as possible.
Not-so-convenient convenience methods
CMTimeGetSeconds may be a friendly and useful method, but its evil twin, CMTimeMakeWithSeconds is anything but friendly to newcomers. Here's its signature:
The first couple of times I used this function, I could not make it do what I wanted. Now that we've gone through all the internals of CMTime, I hope it will be obvious to you where I went astray. I was trying to represent a quantity of 0.5 seconds, so I could get periodic callbacks from an AVPlayer object that was streaming an MP3. I tried to do this:
CMTime interval = CMTimeMakeWithSeconds(0.5, 1);
If you've followed along so far, you already know that interval actually represents 0, not 0.5. It doesn't make sense to ask for a quantity that represents one-half on a number line consisting only of whole numbers, but that's exactly what we're asking for here. Our value gets truncated (rounded toward zero) because our timescale isn't precise enough to represent it.
The Core Media API includes a full complement of functions for constructing, comparing, and performing arithmetic on CMTime. Although performing arithmetic operations on CMTime using these functions is verbose, it is essential to use them if you want to retain precision and integrity. Each of these functions performs special overflow checks and rounding and will set the appropriate flags on the CMTime objects when the need arises.
To add two CMTimes, use the function CMTimeAdd. To compare two times, use CMTimeCompare (the return value of this function follows the convention of comparator functions as used by the C standard library method qsort). To find the larger of two times, use CMTimeMaximum. Read the documentation for plenty of others; this set of functions is quite comprehensive.
Indefinites and infinities: set your freak flag high
The final topic relating to CMTime is the representation of infinities, indefinite values, and rounding. An "indefinite" time is one whose value is unknown. You might receive such a timestamp from an object if you ask for its elapsed time before it's been initialized. The flags value can be checked for each of the following to determine if any of these exceptional situations applies:
Since bitwise OR'ing doesn't appeal to most people, there are useful macros for inferring the presence of these flags. Respectively:
Helpfully, these macros also ensure that the timestamp in question is, in fact, valid. They evaluate to NO if the timestamp isn't valid in the first place.
Also, here's a laundry list of how comparisons amongst different categories of times work: Invalid times are considered to be equal to other invalid times, and greater than any other time. Positive infinity is considered to be less than any invalid time, equal to itself, and greater than any other time. An indefinite time is considered to be less than any invalid time, less than positive infinity, equal to itself, and greater than any other time. Negative infinity is considered to be equal to itself, and less than any other time. Now you know.
I've run out of space for describing where you'll actually be using CMTime objects. But, the odds are pretty good that if you're reading this, you already have a pretty good idea what you want to do with them. AVFoundation objects such as AVPlayer and AVAssetReader use CMTime to talk about time, and there's plenty more where that came from.
If you have suggestions or corrections that would improve this post, please email me. I want this post to be everything I would have hoped for back when I was grappling with this stuff for the first time, so your perspective matters to me.
This article has been translated into Russian by Victor Grushevskiy: О применении CMTime. Thanks for the translation, Victor!
Today, I want to share two anecdotes about my life as a contractor.
About seven months ago, one of the projects on which I was an iOS developer received a stop-work order. In private conversations over the following days, I revealed to one of my colleagues that I had seen the writing on the wall since the inception of the project. I didn't know how to distill my feelings into words at the time, but two things in particular stuck out about the client: lack of total executive commitment, and lack of resources for user experience design.
Let's take the second one first: no UX design resources. The project was to port an existing Windows-only desktop application to the iPad. There was an iPhone project that had been completed by a different consulting team and then brought in-house, but it had performance issues and (in my opinion) a ghastly UI.
In our initial meetings for the new iPad product, it was explained that there would be no UI/UX staff on our iPad project. The presumptive reasons were (a) that the client just wanted to use "stock" UI components and (b) the functionality was a subset of the desktop app, so it could act as a living spec for the UI/UX of the iPad app.
Anyone with app development experience who also has an iota of taste will tell you that this is insanity. But hey, we were all Agile and SCRUM (emphasis on the ummm...). We trundled along on the project, using stock paradigms where possible, and trying to force them where they weren't possible. The only design guidance we got (and I'm not exaggerating) is from the PM, who was using Microsoft OneNote to draw wireframes. We went straight from wireframes to code. "Once more unto the breach, dear friends", and "into the Valley of Death rode the six hundred".
The second troubling symptom was lack of executive commitment. I got the impression that the CTO was lukewarm about iPad-only development from the start. Confirmation came quickly enough. The client was going through a rebranding effort during this project, and out of curiosity I googled the old and new trademarks. I stumbled onto a job posting indicating that the company was seeking full-time "HTML 5" developers. It used words like greenfield development and you choose the technology. I realized pretty quickly that our team was going to get shit-canned. The client had sunk tens of thousands of dollars into this project, but far from throwing their whole weight behind it, they were instead putting out feelers for a whole different kind of development team, a development team that could hit all the latest platforms instead of just iPad. Yes, we were about to get cross-platformed and responsive-designed out of business.
And so we did. Two weeks after the stop-work order, the project was shelved indefinitely.
If there are any lessons learned here, they probably go something like this. First, being Agile does not remove the need for a well thought-out design. Second, sometimes the client needs guidance on what resources to provide, and sometimes they're intransigent because they're playing politics. Sometimes, in fact, the wise thing to do is to see the writing on the wall, collect the check, and start emailing your resumé around.
This second story isn't about abject failure, but about the consequences for a company that chooses to rely on contractors to plug a hole that would be better filled by full-time employees. About 18 months ago, I was brought onto an iPhone project that was already underway. This time, it was an existing Web application that needed to have an iPhone interface.
To make a long story short, because I have more to say about the lessons learned here than the project itself, this made for about eight months of fat checks. It was also a pretty high-stress project, with constantly slipping deadlines and sometimes hurt feelings. It could have been at least two orders of magnitude worse, though. At the end of the day, we shipped, and the product is by most accounts a hit.
I feel the need to mention here a very important fact: both of the companies in these tales are software companies. Their core competency was development, sales, and support of an existing piece of software that had a lot of moving parts and dozens of dedicated individuals in database architecture, programming and IT (not to mention the massive sales teams and managerial infrastructure).
The client was a company that should have focused on hiring better. Not just better people, but better roles. You've probably heard some variant of the adage, don't outsource your core competency. Similarly: if you are a software company, even if your products are in C# and SQL Server, your recruiters should know a thing or two about how to hire for other technologies.
If you have to use a contractor to get your project off the ground, treat them like part of your hiring staff for half of the time. Have them architect your new project, then move them aside with full-time hires. Otherwise, you'll have outsourced a new and potentially large piece of your core competency. There are at least two reasons why this is a problem: incentives and adjacency to the rest of your team.
Perhaps the best, if not only, incentive you can offer to a contractor is higher pay. If instead, you rely on internal resources to take over a project in an unfamiliar technology, they have all the reason in the world to excel (assuming a certain baseline of competence): promotions, esteem from their peers, raises and the rest.
Adjacency to the team is as important as correctly-aligned incentives. A team member will benefit greatly from being able to walk down the hall to a veteran on your mature projects and ask for clarification on business logic, or Web service endpoints, or preferred coding style or whatever. Consultants are nearly always harder to reach (unless you keep them on-site, which is both expensive and of questionable legality).
Well, if both of these companies had taken my advice, I would have been out of a job for most of last year, so I'm glad I wasn't wise enough (or in much of a position) to give it back then. In the mean time, I've had a chance to work with some tremendously effective teams as a hired gun, and I hope I'm able to continue building a track record of excellence. There are an awful lot of lessons you have to learn the hard way, but if you're lucky, you get to have fun along the way and get paid for your trouble.
Let's get one thing out of the way right now. The design of this blog is not unique. It is incompletely borrowed from Dustin Curtis' Svbtle blog platform, and I'm not ashamed to admit that. As far as minimal blog designs are concerned, I think it's one of the best to-date. So, I stole it. I could have used an open source clone like Obtvse, but since I haven't written any front-end code for the Web in a long time (over two years, in fact), I decided to do it all by hand. And since I wrote a custom front end, why not write a custom back end?
Static Site Generation
The fundamental requirements for the back end are pretty slim. I write in Markdown most of the time, since it can be published as-is, or easily converted to HTML or even LaTeX with pandoc. Each blog post consists of two files: a .markdown file and a JSON-formatted .meta file. The filename before the extension in each case is the slug for the post (for this post, it's "feelin-good"). The .markdown file contains only the post contents. The .meta file contains key-value pairs such as author, full title, publication date and tags.
The engine of site generation is a Ruby script that loads all posts into a hash, then generates static pages with a configurable number of posts per page, a static page for each post, and a page for each tag (each post also contains a link to its respective tags). Right now, tags are not paginated, but that could be added in the future. In fact, nothing but the bare-freakin'-minimum is included.
The routing is done with a combination of nginx configuration and a tiny PHP script.
The workflow basically goes: write blog post in TextMate or Mou, cp the default.meta file and edit it to satisfaction, run the engine script, move the fresh-baked files to the server.
I've written perhaps a dozen blog posts in the past eight years. I've spent more time installing Wordpress and fussing over themes than I've spent writing. Each new iteration gets a couple of posts and then mostly lies dormant until it gets swept under the rug. I have done a better job of maintaining permalinks for my posts over the last four or five years, but really, I haven't been at all prolific.
Part of the problem with writing only occasionally is that I hold what I do produce to an artificially high standard. I've never had the inertia built up to just put a lot of things out there. My writing hasn't developed far enough not to be self-conscious, so in hindsight, everything looks a little affected, even twee. I don't think I have enough material for daily posts. Maybe short weekly pieces. Maybe just a write-up of an interesting question I answered on StackOverflow (I'd have three solid years of material if I'd been doing that all along). Or a response to a post on Hacker News.
When I did improv comedy, one of the common things that was said behind the curtain is you have to treat the show like you're performing only for yourself. You can't stand up there trying to give the audience what they want, because neither you nor the audience knows what they want, and any attempt to pin it down will come off wooden, or pandering, or silly. The most transcendent moments in improv are when everyone including the performers get drawn up into the story and explore it in an earnest way without trying to be funny or outlandish. Part of the craft is recognizing when you're not being genuine, because when you're trying too hard, you almost always end up in the trope of "fighting or fucking" where the egos of the players take over and lead to unnecessarily escalated scenarios.
Genuine is delightful. So to the extent that I can use this new platform to be more genuine and consistent, I will. I hope I occasionally get lucky enough to deliver delight.