It can certainly be used as an excuse for laziness, it needs to be weighed along with anything. Optimizing an algorithm in a method that only gets used rarely and that only ever handles a tiny amount of data is a waste of time.
Sometimes O(n^2) algorithms are ok even when O(log n) alternatives exist. If it takes a trivial amount of time to write the slow algorithm whereas it would take a lot more time to write the better one and if you can guarantee the input complexity the algorithm will handle won't exceed a certain range, then it's fine.
Consider a factorial function for integer input & output, for example. What's the best way to implement such a thing?
It actually doesn't matter. The most important aspects are to get the error handling and input bounds assertions right, because 21! is larger than 2^64, and the difference between recursion, iteration, and caching at that scale is probably just noise unless you are calling the function thousands or millions of times a second.
P.S. This is a good reason why clear documentation outlining design decisions and their rationale is important. When someone decides to take some pre-existing code that "works great" and massively expand how it's used without changing it the result can be disastrous if people haven't taken into account the inherent limitations of that code.