2 ms·
Eh - It's good to know when you're taking the slow route, but most times the slow route is fine. It's easy to point to the title piece and assume the right adv
by horsawlarway 4y ago
Eh - It's good to know when you're taking the slow route, but most times the slow route is fine.
It's easy to point to the title piece and assume the right advice to is try to optimize early - but the reality is that the gains mentioned here basically only matter because these libraries are used by millions of developers, and run often.
essentially - don't try to optimize until you have a reason to make that effort worth it. For these libraries - it's worth it.
For the times you're getting asked to fix performance, it's because performance has become a feature that matters enough to have someone ask you to fix it. It's fine to wait until that time to swing back around and pay attention to it. There are thousands of times where that never happens, because the performance was fine taking the scenic route through a string. Plus - that leaves you plenty of low hanging fruit to pick up some easy wins.
---
I think the real story here is not that folks are taking the slow route, I think the story is that the low hanging fruit hasn't been knocked out of these libraries. And really, that goes to show that a lot of software really is supported by a very small number of library authors, who aren't doing it as their day job, for very little in the way of real compensation.
Ex: SVGO is used by 9.1 million people (on github alone) but only has 163 contributors, and only 4 people have more than 10 commits. That means only one in 55,000 users has bothered to add anything. And there's only one real dev for every 2.25 million users. And "users" here also includes entire companies.
- TheCoelacanth 4y agoIt's fine to not optimize from the start, but the examples they gave are of cases where the code is doing something more complex that's also slower. Don't make your solution more complex than it needs to be. Start with the simplest solution and you will often get a faster solution as a side effect.
- horsawlarway 4y agoI disagree with this take. In both examples (the original article, as well as the one posted right above) the code under review was slow but simple. Taking just the two from the comment right above this: Double.parseDouble(foo.toString()) This will work for basically any possible value/type of foo, assuming foo supports .toString(). It will work for NaN, it will work for infinity, it will work if the value is already a string. It's explicitly avoiding the complexity of having to consider those cases at programming time, in exchange for taking the slow route (code someone else has written to already do that for you). Simply casting to double will probably work, but not always - worse, the warnings you get, and the edge cases you might need to deal with will vary significantly across languages. Ex: Java will do different things than C++, which will do different things than C#, Python will vary by flavor (CPython and Jython use different underlying types). Basically - it's saving the programmer a boat-load of complexity (reduces the edge cases down to just the exceptions parseDouble() might throw), in exchange for doing something slow. --- Take the hashmap example right after the double example. Will a hashmap let you speed up some algorithms by avoiding n2 in favor of n? Sure - at the expense of memory size and longer initialization. In most places that's probably a sane call. Is it always the right call? Nope. Would not be ideal for my arduino - the memory is so limited n2 is unlikely to matter most times, and again - the memory is so limited I'd rather go slow and finish than try to go fast and segfault. It's also not the right call when the expected length of the data is always going to be small values of n. If n is always going to be less than 5, I'd bet you good money the hash implementation will be slower in most cases. ---- Basically - optimize when optimizing becomes important, because something is slow and it sucks. Until then... slow is smooth and smooth is fast.
- _aavaa_ 4y ago> This will work for basically any possible value/type of foo, assuming foo supports .toString(). It will work for NaN, it will work for infinity, it will work if the value is already a string. A) the example above was explicitly for int -> double, so the fact that it the path through .toString will work for other types is a benefit we won’t get but which has a cost we’ll have to pay regardless. B) I find it hard to believe that the Double class doesn’t my have a method you could call which will convert an int and catch NaN, Null, and MaxInteger. > In most places that's probably a sane call. Is it always the right call? Just as you’d bet that the hash implemention will become slower, I bet you that only 1 in a million people (if that) would write the Double code we’re talking about as the result of thoughtful consideration. > optimize when optimizing becomes important, because something is slow and it sucks. Until then... slow is smooth and smooth is fast. Slow is smooth assumes that the slow path you pick is sane. There’s also a big difference between having to write code that needs optimization, and writing less code to do a job faster.
- horsawlarway 4y ago> the example above was explicitly for int -> double ????? Show me where the type of foo was defined in that comment... I'll wait. For all we know it was some god-awful custom bucket/container class that's hiding all sorts of polymorphism from you.