Skip to content

Instantly share code, notes, and snippets.

@IrisClasson
Created March 17, 2014 11:50
Show Gist options
  • Save IrisClasson/9597938 to your computer and use it in GitHub Desktop.
Save IrisClasson/9597938 to your computer and use it in GitHub Desktop.
How long should you obsess for the perfect solution before moving on?
Its minor part of a feature, but I’ve been obsessing about the best way to solve this for a while.
To the point where I’m starting to wonder if I’ll ever get this done. It’s not a big problem, not life or death. Might be the tiniest little performance effect (I’m debating with myself the best way to handle references and communication between two viewmodels, and whether or not to use a strong or a weak reference, eager or lazy loading of objects, and whether or not to cache), and of course architectural effect.
I certainly don’t want to mess things up and add a tiny clog, but honestly I’m probably more worried about checking in code that isn’t fantastic as I want to show that I can do a good job. I’ve coded up 5 ways to solve achieve the desired result, and I’ve had two code reviews and three discussions with in total five developers.
At what point do I move on? And how do you know when to move and just pick something?
I feel like I’m analyzing this thing to death.
Would love some advice on this :)
@SuperJMN
Copy link

I see your worries. I have felt the same a lot of times. I myself have halted my side projects for weeks trying to figure out the best way to solve an architectural problem.

I would like to help you, and maybe learn with your code. The communication between ViewModels is something I'm very interested, too.

Can you point me out where to see the classes/methods that are involved in your problem? Thanks!

@FransBouma
Copy link

I always work from algorithm to code, never start with code. So first focus on the algorithm and see whether that's optimal for the feature it's for. It's far easier to change an algorithm than to change code. After I'm confident the algorithm is OK and not inefficient, I implement it in code, add tests to see whether the implementation works or not. Review the implementation and if everything is OK (code indeed implements algorithm, tests indeed show the feature works) I move on to the next. This has proven a productive way to ship a lot of software over the years for me, as there are clear boundaries and dependencies what comes after what and thus when you're done :)

Advantages:

  • If the algorithm is efficient (the 'big O') and the code isn't, the implementation details likely caused the problem (e.g. the linked list in .NET has a very inefficient concat operation. If the algorithm relies on the concat being O(1) (which it should) it will be slow with the .NET linked list).
  • If a test fails, the code implementation is to blame, the algorithm was OK.
  • It separates what you're actually doing from how you're doing it: the algorithm(s) are the program, the code is the executable form of that, the projection of that. If the algorithm is buggy, the code will be too, if the algorithm is sound, and the code bugs, you can focus on implementation details, you don't have to look whether the algorithm is OK too.
  • For many things, there are already well defined algorithms with proven correctness and O notations, so it's fairly easy in many cases to simply implement a known algorithm, or start there.

HTH :)

@martinnormark
Copy link

The longer it takes to develop, the less likely it is to launch

Nothing beats code that actually ships and works. Not-yet-shipped code doesn't offer any real feedback/learning, and as far as I can see it seems that you need real feedback in order to move forward.

@dfar-io
Copy link

dfar-io commented Mar 17, 2014

XKCD post - http://xkcd.com/1205/

@nberardi
Copy link

Whenever I find myself in this situation, of finding the perfect balance between performance and architectural beauty at the cost of time wasted. I remind myself that software is malleable and as long as I stick to good principals for architecture, this piece of software can be changed later on. And most times later on the code becomes simpler and more clear, because the path is better defined.

@tjayr
Copy link

tjayr commented Mar 17, 2014

It seems you're obsessing over perceived performance characteristics and the possible impacts a solution to those perceptions will have on the architecture.

The golden rule, in my view, regarding performance is to never take action without data. So load test the solutions you have readily available to get that data - now you can make informed choices on what to do next regarding architectural changes etc. The first implementation of any algorithm or indeed product will never be perfect, make a best effort, get feedback, refine it and repeat as necessary. If the performance hit is negligible or doesn't matter (based on the performance criteria of the architecture), having considered the reviewers comments, you choose the most readable/understandable solution - in your view.

Don't worry about code that isn't fantastic - you will never please everyone with your code, but continuous feedback is essential - that feedback comes from peers, customers and the software/hardware itself. You should seek it out as often as possible and don't be concerned about perceptions of doing a good job, that will have nothing to do with a couple of commits of code but your contributions over time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment