Archive for August 2011
Recall a certain blog post about Expensify and .NET? Odds are you stopped reading about five paragraphs in, and possibly missed how ”.NET on your resume isn’t an instant showstopper” only that it will “raise questions during the phone screen”. Similarly, you might have missed that .NET is the “only choice” for Windows Phone 7 development. Well at risk of dredging up old grievances, I’m happy to announce:
Expensify is Hiring a .NET Programmer!
(Windows Phone coders please apply)
As for what we’re building, it’s no secret: we’ve got a cross-platform mobile layer that needs porting to WP7. It currently works on Android and BlackBerry, and we’re about to launch an iPhone version. We’re thinking of open-sourcing it if there’s adequate interest; leave a comment below if that appeals to you. Either way please check out our Elance post for complete details, or just read on:
Port Expensify cross-platform layer to Windows Phone 7
Hello! Expensify has apps for iPhone, Android, BlackBerry, and webOS. A little known fact is that we built our own cross-platform layer, such that we have “write once run everywhere” on these platforms — using native controls. Your mission, should you choose to accept it, is to port this platform to Windows Phone 7.
I somewhat famously blogged about how much I like .NET for Windows Phone, so I’m very excited to start on this project!
It works like this on all other platforms, so we need you to build the WP7 equivalent:
- However, some JS functions are “non-blocking”, namely network calls, camera actions, and GPS queries. These should return immediately and be processed in another thread (or even by kicking off an external app and waiting for a response). When they complete, like UI events, the callback should come from the one single JS thread.
- Persistent storage is currently very simple, using flat files on the file system. (Typically writing and reading JSON files.)
We are looking for a long-term contract, ideally with the opportunity to hire on-site in SF if all goes well. (Remote hiring or just remote long-term contract is also fine.) Accordingly, we prefer individuals over teams — especially individuals who like what’s written here: https://www.expensify.com/jobs/need I should also mention that if you’d like to skip the contract and go immediately into hiring talks, that’s fantastic too.
This is a big project, so I’d recommend we split it up as follows:
1) Develop proof of concept. It is a standalone app executing in the emulator that instantiates a JS engine that loads a “hello world” file, which calls a single “alert” function to pop open an alert box. For simplicity, please include a “fixed bid” for this first deliverable, along with an hourly rate that we’ll switch to for future milestones.
2) With proof of concept in hand, flesh out the remaining UI controls. It includes what you’d expect — text, number, date picker, checkboxes, images, etc. A complete specification will be provided; if you prefer we can also handle this second milestone as a fixed bid.
3) Add networking and camera. Historically this is the part that gets hard, as for some reason HTTPS support on every single other platform has been dicey — especially when uploading binary images. This was true for iPhone, Android, BlackBerry, and webOS, so I expect it’ll be true for WP7 as well. Accordingly, I suggest we switch to an hourly rate for this.
4) Release to the Windows Marketplace for Mobile and interface directly with uses to diagnose and resolve issues experienced in the field.
How does this sound? Please let me know, I look forward to talking soon!
Founder and CEO of Expensify
Anyway, I look forward to hearing your cogent, well-considered comments below. Thanks!
Years ago Witold and I joked that performance is a problem we’d “love to have”. It means that you have so many people using and liking the thing you’ve made that it’s starting to slow down. After all, an iPhone has enough horsepower to power most websites: it really takes a lot of work to overload an actual business-class server anymore. If you’re experiencing genuine slowdowns, it’s a sign that things are on the right path. It’s a problem you should love to have.
However, it’s still a problem. In our case, things aren’t quite as snappy as we’d like. We’ve increased from 3 to 5 datacenters, vastly increased hardware, and the users keep coming. So we’re embarking on a much more deliberate optimization campaign than we’ve ever done (or had need to do) in the past. And that’s great because optimization it’s fun! It’s full of all sorts of “classic” engineering problems — phrases like “Big O” get tossed around with nary a chuckle.
But like most fun things, at its heart lurks a deep evil. Here’s what I advised our team, and I thought I’d share it with you as a public awareness campaign highlighting a universal problem.
Premature optimization is the root of all evil. I mean that in the most literal and expansive way possible. Resist this devil with all your might. Here are some tips:
1) DON’T OPTIMIZE IF YOU DON’T KNOW IF IT’S SLOW.
I repeat: don’t make something faster if you don’t actually know how fast it is. It’s possible — in fact, highly probable — that it’s actually adequately fast as is. I’d estimate that 80% of optimizations have absolutely no beneficial effect, and actually make code slower and less maintainable. Don’t be “that guy” who spends all day optimizing something that doesn’t need it, while ignoring the enormously huge low-hanging fruit all around.
2) BENCHMARK BEFORE OPTIMIZING.
Optimization is a field where you can spend an unlimited amount of energy accomplishing precisely nothing of value (or even less). The best protection against this is measure its real-world performance before starting, as this is the only effective way to prioritize areas to optimize. The best measure is that which is experienced by the end user.
3) BENCHMARK AGAIN AFTER OPTIMIZING.
If you don’t know that your optimization worked, it’s safest to assume it didn’t — just like the vast majority of optimizations. If it didn’t, then revert the change. It doesn’t matter how long you spent building some fancy caching layer or tweaking settings in ways that “I’m sure” are better. Don’t trust your gut, trust the numbers. If the numbers say you’re wrong, you’re wrong.
Note: Optimizing is not the same as refactoring, though often they go hand in hand. If you’re refactoring code to make it cleaner and simpler, then it doesn’t matter if it goes faster, so no need to revert a cleanup if it has no speed improvement.
4) FOCUS ON ABSOLUTE TIMES.
It means nothing to say that something is 50% faster if it was already fast enough to start. Don’t even think about problems measured in “miliseconds per X” until all of the “seconds per X” problems are already handled.
5) DO THE MOST IMPORTANT OPTIMIZATION FIRST.
Not the one you just found, or the one that’s been nagging you, or the one that lets you use that really awesome algorithm. This is the absolute hardest of all: when you find something new, add it to the list, but always start with the optimization at the top of the list. If the thing at the top of the list hasn’t already been benchmarked, benchmark it. If after benchmarking it you find that it’s actually not as important as something else on the list, log your benchmark results, then put it back on the list at a lower priority.
6) SHOW LOYALTY TO THE USER, NOT TO A LAYER.
Don’t optimize something merely because it’s the slowest in a particular layer; always do whatever increases end-user performance first. Trace the issue and benchmark through all layers before deciding how to speed it up. Leave no layer unturned.
7) CHANGING USER EXPECTATIONS IS THE BEST OPTIMIZATION OF ALL.
Remember, the goal is to make the user satisfied. One way is to actually live up to the user’s expectations. Another is to change their expectations by adjusting the flow in such a fashion that they just don’t expect as much. Some blocking operation really slow? Make it asynchronous such that the user doesn’t care how long it takes.
8 ) BROADCAST BIG PLANS BEFORE YOU DO THEM.
Before building out some really crazy ambitious awesome thing, email to the team explaining what you’re going to do. *Sell* your change, based on the benchmarks. Be proud of your plans; if you feel hesitant it’s probably a sign that you don’t really know what you’re doing or why — and thus probably shouldn’t.
I’m serious, premature optimization is what sinks ships. It’s the tarpit of any engineering organization; it’s where clean and simple architectures go to die. Resist the devil. Be strong.
When we say we work hard and play hard we mean it. A week ago we went to the shooting range in San Rafael. Naturally, we had a blast…
Photo Credits: Thomas Genin, Ayumi Yu
You should join us
Good news everyone!
You can now crop and rotate your receipts in Expensify!
Adjust the image as you like, and click the check to save!
How do I undo?
Previous versions of the image go to Deleted Receipts. Change the receipts dropdown from “Unreported Receipts” to “Deleted Receipts”, and you can restore old receipts.
After a quick halftime break, let’s resume the second half of the series. As mentioned in the past, this is the fourth in a six-part series elaborating on a presentation I gave at the AlwaysOn OnMobile 2011 conference titled “Disrupting the Enterprise”. I suggest reading from the start (or watching the video) and then continuing on below.
Recap: The Three Conditions Underpinning Sales (N+1).0
So there are three interesting conditions at work:
- The “Consumerization of IT” empowers employees to promote products up the chain in an enterprise
- “Word of Mouth” has become a “Winner Takes All” phenomoneon where early dominance of the global conversation becomes self-reinforcing
- There was a one-time “Cascade of App Stores” that gave a substantial and lasting advantage to first movers
The upshot of all of this is I feel there is an enormous opportunity to reach into previously inaccessible parts of the market using a sales strategy that I call Sales… 3.0? 4.0? Let’s just say 10.0 to get ahead of the curve. The very modestly named “Sales 10.0″ strategy conists of three principles:
Principle #1: The Bottom Up Adoption Curve
Many industries share a common chart: a very wide base of customers at the “bottom” of the market, narrowing down to a very pointy tip of customers at the “top”. What “bottom vs top” actually means and how it’s quantified depends on the market. But if you’re reading this blog, odds are you’re targeting the “bottom” of the market while some other big company has a stranglehold on the “top”.
At some point, the big company at the top will decide it wants to capture some of the action down at the bottom. It’ll do this by instructing its massive salesforce to start going after smaller deals — probably by adjusting their commission incentives to make smaller deals more attractive than they’d normally be (or by hiring a new sales force devoted to just this). If they’re really serious, they’ll come out with some new product targeted squarely at the small business space.
But don’t worry, because odds are no matter what they try, it’s not going to work. The product and skills needed to operate in and maximize the value of the top of the market just don’t translate down market. Small businesses aren’t small versions of big businesses, they’re an entirely different beast. Any company optimized to hunt whales just isn’t suited to trap squirrels.
This is where the “bottom up adoption curve” comes into play.
In the top-down sale, you typically start talking with senior management — nobody really experiences the product until they’ve already signed off on it. But the bottom-up sale reverses the process, giving a trial of the product straight to the rank-and-file employees, before senior management even hears of it. So while a top-down salesperson would fight tooth and nail to get a limited trial authorized by senior management, the bottom-up product just walks in and starts a trial on day one. Top-down requires some high-level introduction to start a conversation with a new customer, while bottom-up can start with anybody, anywhere in the company — the lower the better. While the top-down company builds a wide range of complex features that appeal to management, the bottom-up company builds the few core features that the actual users of the product love.
The end result is the bottom up adoption curve reaches out directly to the innovators in every company, empowers them to initiate a limited trial without the need for anybody’s permission, and then champion the results internally — essentially giving you an “inside man” pulling for you in every sales lead.
So it’s “bottom up” because you start with the users first, and percolate up to senior management only after the trial has already successfully completed (and thus, there’s no reason to say no). And its an “adoption curve” because it takes a graduated “innovators first” strategy where those who come before learn and train the people who come after (as opposed to a top-down sale where all users are signed up at the same time). It allows your product to be pulled into organizations by the people who need it most, and then sold to all internal stakeholders by someone intimately familiar with the local conditions — all without you ever picking up the phone.
So it’s a system that definitely works in the small business space. It’s very hard to design a product to accomodate it, and it’s very hard to get all the incentives to line up. But when you do, it takes off under its own steam, with each new user expanding your salesforce — and thanking you for it. Everybody wins.
But it’s also “bottom up” in another sense: with this technique, you start with the bottom of the market, and gradually work your way “up” to the top.
Granted, this is the only thing that will work at the very bottom of the market. The deals are so small, and there’s just so damn many of them, you absolutely need to have something like this to survive. The most important feature you ever build is the one that finds the next customer, automatically, while you’re asleep.
And to be fair, if you were only going to sell to the top of the market, you wouldn’t bother with this. It’s really tricky stuff, and it’s so much easier and more effective to just go out and get a sales force (assuming the cost of sale is substantially less than the revneue it brings).
But if you *do* start out at the bottom, and if you *have* already gone through the trouble to make this work… why not use it upmarket as well? After all, there’s nothing about this process that doesn’t work in large companies as well as small. Sure, big companies have bigger requirements. And you might need to get more clever about how exactly you support your internal champions — giving them the tools they need to start a trial without anybody noticing, and promote your product up the food chain in a non-disruptive fashion. But maybe it’ll work there too?
The bottom up adoption curve is a strategy for not merely taking over companies, but taking over markets. And as we’ll see next week, holding onto them forever when you get them.
Thanks for reading, keep an eye out here to read more next Friday!
Previous: A Cascade of App Stores (3/6)
Receipt scanning has been sweeping the nation by storm and many of you have been burning through receipt scans faster than they could be purchased. Good news for all of you – receipt scans can now be refilled automatically as they start to run out! Head over to your Settings -> Receipt Scanning page, turn on automatic scan refilling and select which package you want to reload with when the remaining receipt scans starts to get low.
First time purchasing scans and want to just “set it and forget it?” Check the box at the bottom of the purchase dialog and we will refill your account with the same amount of scans each time you run dry. Happy scanning!
Considering ditching your external receipt scanner or shoebox stockpiling? Give our receipt scanning a try!