News for hackers. Stuff that matters.
Re:O(n^2), again, now in Windows Management Instrumentation by harikb on Monday December 09, 2019 @10:32AM (#21743439)
A gem

> Dawson’s first law of computing: O(n^2) is the sweet spot of badly scaling algorithms: fast enough to make it into production, but slow enough to make things fall down once it gets there

Re:O(n^2), again, now in Windows Management Instrumentation by rcthompson on Monday December 09, 2019 @11:04AM (#21743734)
I think the other reason O(n^2) is a "sweet spot" is that it often arises from one O(n) algorithm calling another O(n) algorithm in each iteration, resulting in O(n^2) overall. Very often it's ultimately because the inner O(n) algorithm should have been implemented as O(1), but nobody bothered because it was never intended to be called in a loop.
Re:O(n^2), again, now in Windows Management Instrumentation by masklinn on Monday December 09, 2019 @12:21PM (#21744386)
> it often arises from one O(n) algorithm calling another O(n) algorithm in each iteration, resulting in O(n^2) overall.

https://accidentallyquadratic.tumblr.com was / is pretty much an entire blog dedicated to this.

Re:O(n^2), again, now in Windows Management Instrumentation by crankylinuxuser on Monday December 09, 2019 @11:09AM (#21743759)
This is absolutely the better analysis. Many times, especially in agile-world, you get away with things as fast and as reasonable as you can. And that usually means O(n) as it is perfectly acceptable for a single call... But when an O(n) calls another O(n) is where you run into trouble.

But at the beginning, nobody was planning for that call to be fast - implicit requirements lead it that way.

In some ways, being able to identify and detect resource usage is what is nice about waterfall. Identification of critical API calls and respective timings would be integral to continue building the GUI elements. But we all know how waterfall is poo-pooed these days.

Re:O(n^2), again, now in Windows Management Instrumentation by pjc50 on Monday December 09, 2019 @11:29AM (#21743925)
> Identification of critical API calls and respective timings would be integral to continue building the GUI elements. But we all know how waterfall is poo-pooed these days.

If you've worked out which API calls are happening and how often, you've already written most of the application. It's just that it might be on paper or in pseudocode.

Waterfall was abandoned because getting to that level of detail takes far too long for management to accept and it's easier - sometimes orders of magnitude faster - to write the thing as actual code, try it, and then see what needs improving. And see what was wrong with the requirements.

Re:O(n^2), again, now in Windows Management Instrumentation by retrovm on Monday December 09, 2019 @11:38AM (#21743995)
That presupposes that you can start with a big pile of bad APIs and somehow incrementally approach something worth having. That's not consistent with my experience. In my experience the innermost APIs, the ones that get written down first, are effectively cast in stone and dictate the quality of the whole product, forever. The first draft of a system is the one that should have all its APIs worked out with a pencil before any code is written. You get these accidental complexity explosions precisely because someone thought it was easy and obvious to write a function returning std::vector<string> (or whatever) and didn't consider from the caller's point of view that making the function take an output iterator might be less complex.
Re:O(n^2), again, now in Windows Management Instrumentation by jacobolus on Monday December 09, 2019 @03:06PM (#21745930)
You are right. It is typically more effective to write one implementation as a hacky prototype, play with it a bit, throw it away, and then rewrite a production implementation from scratch, so that the mistakes of a design made by someone inexperienced don’t get baked in forever.

Unfortunately there are cultural/psychological factors which often preclude or discourage this method, even if it would save time and produce better code in the medium term than either exhaustive planning up front uninformed by practice OR just iterating the initial broken version to continually meet new requirements.

Re:O(n^2), again, now in Windows Management Instrumentation by BlueTemplar on Monday December 09, 2019 @03:21PM (#21746089)
Lol, ninjaed, see above.
Re:O(n^2), again, now in Windows Management Instrumentation by BlueTemplar on Monday December 09, 2019 @03:19PM (#21746070)
I've been taught waterfall a couple of years ago. We were supposed to do our project using waterfall (but at least with weekly meetings with the "customers").

My suggestion of building a first test version to, amongst other things, at least get our feets wet with the programming language (which most of us had hardly any experience with), then throw it completely away and restart "from scratch" (but with a better idea as of what we were supposed to do) was rejected.

Re:O(n^2), again, now in Windows Management Instrumentation by TimTheTinker on Monday December 09, 2019 @11:25AM (#21743886)
Waterfall refers more to the fact that further work (development, testing, or deployment) has to wait for someone else to finish something else first. Multiply that by how many “steps” something has to go through before being released. This implies everyone is taking work in large chunks instead of small iterations, and that too much is being planned too early instead of learning as you go.

Taking things iteratively, small iterations, delaying decisions, learning as you go — that’s what agile development is. And all the stuff you mention above is possible when developing with agility.

Re:O(n^2), again, now in Windows Management Instrumentation by ComputerGuru on Monday December 09, 2019 @12:35PM (#21744529)
> Many times, especially in agile-world, you get away with things as fast and as reasonable as you can.

Which has led to the ridiculous software bloat we have today. This always MVP, break fast, break often garbage needs to die.

Re:O(n^2), again, now in Windows Management Instrumentation by chousuke on Monday December 09, 2019 @03:11PM (#21745989)
I feel like the concept of an MVP is often abused. It shouldn't be a thing that somehow works with bubblegum and luck; it should still be "solid". The point ought to be to leave out features, not quality.
Re:O(n^2), again, now in Windows Management Instrumentation by NateEag on Monday December 09, 2019 @04:48PM (#21746988)
When you leave out features and quality, you have a proof of concept.

Those are valuable things to build, IMO. Just make sure you leave out enough features that it cannot be pushed into production once someone else sees it running.

Re:O(n^2), again, now in Windows Management Instrumentation by ludamad on Monday December 09, 2019 @11:17AM (#21743825)
Right, if we consider O(n) "ideal" (for many domains, this is true), we can consider processing per item as a more convenient metric. If you go above, say, O(log n) processing per item, you're in trouble proportionate to the unintended success of this portion of the code. Very easy to write a sloppy utility with a nice API, only for it to be 'the perfect fit' for someone else's tight deadline, become an idiom in the code, finally see a 10,000 entry example much later
Re:O(n^2), again, now in Windows Management Instrumentation by cross_wiber on Monday December 09, 2019 @01:03PM (#21744805)
That's a good point. It explains why you can very often unintentionally end up with an O(n^2) algorithm in the first place, and Dawson's law then explains why no one bothers to fix it until it's too late.
Re:O(n^2), again, now in Windows Management Instrumentation by brucedawson on Monday December 09, 2019 @04:50PM (#21747003)
Hey, it's Dawson's first law of computing. I have more planned, and it's important to distinguish them.
Re:O(n^2), again, now in Windows Management Instrumentation by savingGrace on Monday December 09, 2019 @11:44AM (#21744045)
I often see O(n^2) algorithms that can be reduced to O(2n) at the very least. One of the best things I gained from school was the red flag that fires off in my mind any time I see a loop nested in a loop.
Re:O(n^2), again, now in Windows Management Instrumentation by shantly on Monday December 09, 2019 @11:58AM (#21744172)
A little experience gets you that same red flag instinct in a hurry, too.

[EDIT] it also makes you hesitate & second-guess and worry and experiment a bunch when contemplating using a recursive algorithm, which is deeply counterproductive in interviews where the expected behavior is so often "apply recursion, instantly and without hesitation" :-)

Re:O(n^2), again, now in Windows Management Instrumentation by nikanj on Monday December 09, 2019 @01:06PM (#21744831)
Unfortunately interviews seem to be all about dogma, and if you even mention performance you will get dinged for premature optimization.

It’s like a postmodern religion where premature optimization is the cardinal sin, and you are supposed to burn as many cycles as possible to demonstrate that you are of good faith

Re:O(n^2), again, now in Windows Management Instrumentation by WorldMaker on Tuesday December 10, 2019 @04:49PM (#21757228)
On the flipside, I've met different sorts of interviewers that ding someone for writing something intentionally unoptimized in the spirit of avoiding premature optimization for algorithmic clarity, because don't they have rote knowledge that "x is faster". Dogma on every side of the fence. (Also, continuing proof that technical interviews will never be objective evaluations of skill.)
Re:O(n^2), again, now in Windows Management Instrumentation by stevefan1999 on Monday December 09, 2019 @12:27PM (#21744438)
you shouldn't call it O(2n), as there is already a constant inside of O(n), because it becomes 0 <= f(x) <= c*2n given a random f(x)
Re:O(n^2), again, now in Windows Management Instrumentation by Tyr42 on Monday December 09, 2019 @01:50PM (#21745202)
Yet, we understand exactly what he means. Sometimes it's useful to show an un-reduced intermediate step to facilitate understanding, even if you could reduce it further.
Re:O(n^2), again, now in Windows Management Instrumentation by vanderZwan on Monday December 09, 2019 @01:18PM (#21744920)
Eh, you're technically correct but when used as a point of relative comparison to an O(n²) algorithm I think there's some merit to it, because it actually gives some sense of constant overhead within the context.
Re:O(n^2), again, now in Windows Management Instrumentation by protomikron on Monday December 09, 2019 @01:44PM (#21745149)
> Eh, you're technically correct [...]

The best kind of correct. Calling it O(n) then is the best way to express the performance improvement - I think that's the whole point of Big-O notation.

However I agree that for smaller n one should not underestimate the constant factor impact.

Re:O(n^2), again, now in Windows Management Instrumentation by aflag on Monday December 09, 2019 @02:07PM (#21745332)
The point was that you can often convert nested loops into two loops that are not nested. O(2n) conveys that, O(n) does not.
Re:O(n^2), again, now in Windows Management Instrumentation by BlackFingolfin on Monday December 09, 2019 @02:47PM (#21745741)
Actually O(2n) did not convey this for me at all, all it did for me was cause confusion. If this ("turn it into two not nested loops") was indeed intended, I'd suggest to spell it out, not abuse notation
Re:O(n^2), again, now in Windows Management Instrumentation by thaumasiotes on Monday December 09, 2019 @04:39PM (#21746905)
> If this ("turn it into two not nested loops") was indeed intended, I'd suggest to spell it out, not abuse notation

O(2n) is not an abuse of notation. It's just as well defined as O(n). The fact that O(2n) is a subset of O(n) is a theorem, not part of the definition of the notation.

Re:O(n^2), again, now in Windows Management Instrumentation by enedil on Monday December 09, 2019 @06:40PM (#21747931)
It's a subset, but also a superset.
Re:O(n^2), again, now in Windows Management Instrumentation by thaumasiotes on Monday December 09, 2019 @06:46PM (#21748001)
Yes? But to replace O(2n) with O(n), you only need that it's a subset.
Re:O(n^2), again, now in Windows Management Instrumentation by enedil on Monday December 09, 2019 @08:07PM (#21748622)
You have your point.
Re:O(n^2), again, now in Windows Management Instrumentation by aflag on Monday December 09, 2019 @03:09PM (#21745972)
Interesting, I hear people spelling out constants all the time when using the O notation to put emphasis where they want. I guess that's not really as universal as I thought, but I still think it's a good way to express.
Re:O(n^2), again, now in Windows Management Instrumentation by thomasahle on Monday December 09, 2019 @04:56PM (#21747056)
It can cause more confusion though, if say you write O(kn), but the oh-notation hides a factor k^3, then it would be better to just write O(n). Or write O_k(n) to signify a hidden dependency on k. Or best of all, just write out k^4 n without any ohs at all.
Re:O(n^2), again, now in Windows Management Instrumentation by TravHatesMe on Monday December 09, 2019 @01:38PM (#21745101)
What if the constant were massive? Then the coefficient might not be significant in practise. O(2n) might be worse than O(n+99999999), they both reduce to O(n) though. It is a classification.

Personally I would prefer to use different semantics to express that. It seems big O notation often carries a separate meaning in parlance.

I thought big O notation was about classifying function growth irrespective of the coefficient/constant. Does it not grow at all with respect to n? great you are O(1). Does it grow linearly? cool you are O(n). Logarithmically? Quadratically? In my mind, this kind of analysis aligns with big O notation.

Re:O(n^2), again, now in Windows Management Instrumentation by baddox on Monday December 09, 2019 @02:11PM (#21745366)
If constant factors are significant in practice and the size of the input is not significant, then big O notation is not the right tool for the analysis, and that's perfectly fine. For instance, we generally don't talk about big O notation when comparing the performance of SSDs and spinning HDs.

Big O notation is for describing how the performance of an algorithm changes as the size of its input changes. If the size of the input is not a significant concern, then it's totally fine to not use big O notation for analyzing the problem.

Re:O(n^2), again, now in Windows Management Instrumentation by bsder on Monday December 09, 2019 @03:48PM (#21746382)
Asymptotically, that's true.

In reality, O(n) and O(2n) can be quite different for small n. As can O(n)+k0 and O(2n)+k1. Or worse, O(n^2)+k2 where sufficiently large k0 and k1 make the quadratic system better because it's k2 constant is so much smaller. Setup time matters.

Nowadays, you rarely have enough elements that the asymptotic behavior is the defining performance characteristic.

Re:O(n^2), again, now in Windows Management Instrumentation by esoterica on Monday December 09, 2019 @09:51PM (#21749179)
O notation is asymptotic by definition. The sentence “O(n) for small n” is completely meaningless. O(n) cannot never be different from O(2n) because they refer to the exact same set of algorithms.
Re:O(n^2), again, now in Windows Management Instrumentation by mantap on Tuesday December 10, 2019 @07:06AM (#21751699)
Theoretically yes but practically no. Theoretically Big O notation is defined as a limit that goes to infinity but in practice there's no such thing as infinity and saying that an algorithm's runtime is in O(n) implies certain things about its behaviour for finite n, that's kind of the point. And it's perfectly possible for an algorithm to be defined piecewise on the input size and so saying it has runtime O(n) for small n is a statement that has practical significance.
Re:O(n^2), again, now in Windows Management Instrumentation by naniwaduni on Tuesday December 10, 2019 @08:19PM (#21758634)
For a moment I assumed that this was another of those cases where copy-pasting to HN lowered a subscript.

Then my brain asked why you'd want to reduce a quadratic algorithm to exponential.

Re:O(n^2), again, now in Windows Management Instrumentation by TravHatesMe on Monday December 09, 2019 @12:33PM (#21744506)
O(2n) = O(n)
Re:O(n^2), again, now in Windows Management Instrumentation by leetcrew on Monday December 09, 2019 @11:38AM (#21743996)
sometimes it was correct to choose O(n) instead of O(1). if you know you're only going to have very few elements, linear search on a vector can be faster than a hashtable lookup or rb-tree traversal and use less memory for the data structure. later on some clown decides to expose your private function for their own convenience and starts calling it with thousands of elements.
Re:O(n^2), again, now in Windows Management Instrumentation by mrec on Monday December 09, 2019 @11:44AM (#21744048)
You're not wrong, but IMHO the proper place for that sort of optimization is inside the dictionary class/module/whatever. It knows why the optimization is there and the conditions under which it makes sense.

For application code it's probably better to express clearly what you're trying to do, in this case keyed lookup. Throwing in a linear search at that level isn't just dangerous, it's potentially confusing to people reading the code later.

Re:O(n^2), again, now in Windows Management Instrumentation by cogman10 on Monday December 09, 2019 @03:00PM (#21745874)
Depends. Sometimes the key isn't easily hash or comparable. For example, I know of a few case where the keys looks something like "if (a > b and c < d) or (a < b and d == b)".

Now, that doesn't mean you can't hash a, b, c, and d. It just means that the logic around doing the lookups is nontrivial.

When you are talking about < 100 elements, sometimes the consideration is "Welp, this is < 100, so lets just n^2 it".

Re:O(n^2), again, now in Windows Management Instrumentation by mehrdadn on Monday December 09, 2019 @03:04PM (#21745903)
> where the keys looks something like "if (a > b and c < d) or (a < b and d == b)"

Confused, what do you mean when you say the key is an "if" statement?

Re:O(n^2), again, now in Windows Management Instrumentation by z92 on Monday December 09, 2019 @03:34PM (#21746221)
He probably meant, the lookup in the list is a conditional lookup based on a logic, instead of a simple key string.
Re:O(n^2), again, now in Windows Management Instrumentation by mehrdadn on Monday December 09, 2019 @03:53PM (#21746427)
I'm confused what the variables are in this example—what's already in the container vs. what is being looked up. If we conceptually don't even have a proper mapping to begin with, then it doesn't make sense to ask whether it's hashable or comparable or not in the first place. If we do—then what is the "key" in this example?
Re:O(n^2), again, now in Windows Management Instrumentation by cogman10 on Monday December 09, 2019 @04:10PM (#21746618)
Let me preface this by saying I work in finance and rules are weird.

This comes up frequently when looking for fuzzy "duplicates".

For example, sometimes you get data from 2 sources, one will send it through with 0.01 precision. Another will send it through with 0.001 precision. You can't hash or compare that.

Things get more tricky when different finance institutes used different terms for the same entity.

That doesn't mean you can't avoid n^2 duplicate searches. It just means you have to be smart about how you group things.

Re:O(n^2), again, now in Windows Management Instrumentation by mehrdadn on Monday December 09, 2019 @04:49PM (#21746993)
Right, so you have an application where you don't genuinely have a dictionary -- e.g., inserting items in a different order can result in a very different outcome even when all the keys are distinct, or even worse, inserting two keys and then removing a third can give entirely different results depending on the order in which you inserted the first two. (Or other arbitrary things depending on your application.) That can of course come up; it's just been quite confusing for me to see a fuzzy search scenario like this presented as a counterexample when (at least to me) the discussion seemed to be about proper mappings.
Re:O(n^2), again, now in Windows Management Instrumentation by bentcorner on Monday December 09, 2019 @09:34PM (#21749091)
You can always assert on insertion that n <= c. Or track the max size and assert on destruction.
Re:O(n^2), again, now in Windows Management Instrumentation by wesammikhail on Monday December 09, 2019 @08:05PM (#21748603)
A useful heuristic from my CS professor: always treat every tab (indentation / complexity) to be equivalent to a cart that you are attaching your horse. Add enough carts (complexity) and you will soon be asking yourself why your horse isnt a nuclear reactor instead?
Re:O(n^2), again, now in Windows Management Instrumentation by jtolmar on Monday December 09, 2019 @01:18PM (#21744915)
Programming languages have native support for O(n) algorithms in the form of for loops. You can compose as many of those as you want to get a huge polynomial, but you have to go out of your way and do something a bit weird to get an exponential run time.
Re:O(n^2), again, now in Windows Management Instrumentation by saagarjha on Monday December 09, 2019 @05:08PM (#21747154)
Recursion is a pretty good way to exponential quickly.
Re:O(n^2), again, now in Windows Management Instrumentation by kortilla on Monday December 09, 2019 @02:22PM (#21745488)
What? It’s trivial to go exponential.

  for i in n:
      for j in n:
          whoops(i, j)
Re:O(n^2), again, now in Windows Management Instrumentation by reggieband on Monday December 09, 2019 @02:37PM (#21745639)
That is polynomial time (specifically quadratic).

See this stack overflow on polynomial vs. exponential: https://stackoverflow.com/questions/4317414/polynomial-time-...

Re:O(n^2), again, now in Windows Management Instrumentation by _wldu on Monday December 09, 2019 @06:07PM (#21747659)
Two for loops, one nested under the other, both upto N is clearly O(N^2) in the worst case. Three for loops (in the same manner) is O(N^3).
Re:O(n^2), again, now in Windows Management Instrumentation by a1369209993 on Monday December 09, 2019 @09:19PM (#21749013)
Actually, that should be:

  whoops(n):
    for i in n:
      whoops(n-1)
Your version is merely quadratic.
Re:O(n^2), again, now in Windows Management Instrumentation by trehalose on Tuesday December 10, 2019 @12:08AM (#21749769)
I don't quite understand your code, but if I'm guessing correctly that n is an integer and "for i in n" means in human terms "for all non-negative integers less than n",

that is not exponential, that is actually factorial, which is superexponential. Uh, or close to factorial, I'm not sure exactly. Testing it in python right now, incrementing a counter each time whoops is called, I'm seeing a relationship that looks like whoops(n) == n * whoops(n-1) + 1 That is interesting.

Re:O(n^2), again, now in Windows Management Instrumentation by a1369209993 on Tuesday December 10, 2019 @06:20PM (#21757916)
> that is not exponential, that is actually factorial, which is superexponential

Fair point; I should have given:

  whoops(n):
    if(!n) return
    for i in 2: whoops(n-1)
I think it's clear that it is "trivial to go exponential", though. And for that matter, also trivial to go superexponential apparently.
Re:O(n^2), again, now in Windows Management Instrumentation by esotericn on Monday December 09, 2019 @02:29PM (#21745550)
That's n^2.
Re:O(n^2), again, now in Windows Management Instrumentation by lmm on Monday December 09, 2019 @07:12PM (#21748227)
I don't think that's a real insight. You could equally say that O(n^3) should be a sweet spot because you can nest a loop 3 deep, and so on for n^4, n^5 and so on. But we don't see these cases making it out into the wild because they're caught in testing.
Re:O(n^2), again, now in Windows Management Instrumentation by Tade0 on Monday December 09, 2019 @11:54AM (#21744142)
Or those two should have been combined into O(nlogn) via sorting.
Re:O(n^2), again, now in Windows Management Instrumentation by 52-6F-62 on Monday December 09, 2019 @01:50PM (#21745203)
Or if you've already made allowances for the memory usage, you can also check to see if you can write your O(n^2) nested loops as O(n) + O(n) depending on the shape of your data.
Re:O(n^2), again, now in Windows Management Instrumentation by mehrdadn on Monday December 09, 2019 @03:09PM (#21745968)
Speaking of O(n^2) algorithms (if it's OK for me to promote my own writing on this recently?):

I recently illustrated how they can even occur as a result of algorithms being slow by a constant factor.

I thought it might be useful for others, so I posted it here: https://news.ycombinator.com/item?id=21745911