Make it work. Then make it maintainable. Then polish it to make it more ideal.
When it works it can be spaghetti and lack testing and filled with hacks. After you make it maintainable it can still be less than ideal — some hacks here and there in leaf functions but things are localized and understandable and non-brittle (ie good testing coverage, design which has appropriate abstraction, refactors to promote test ability, no more spaghetti etc etc). Then in the final step you polish the stuff to gold (ie use better solutions or improve performance). It is the only way.
1. Make it work 2. Make it performant (always, but within reason) 3. Clean up your mess to prevent future mistakes
I claim that "if too slow" can't be judged because you almost never have the slowest possible target device.