News for hackers. Stuff that matters.
Re:14,000x Speedup (2015) by hinkley on Tuesday October 13, 2020 @12:04PM (#24766848)
I was asked once in an interview what the hardest part of programming was, and I said it wasn't Order of Complexities, it was the C constant within it. Interviewer was not subtle in thinking that was stupid.

My rationale was - and is - that C is not sexy. It's hard to motivate people to look into it, and it's often hard work because a sort algorithm or a lookup table tend to be compartmentalized, while C issues are diffuse - they're literally everywhere, and they don't always show up on a flame graph. On one project I got a 2x improvement in overall performance by fixing issues that weren't visible in the perf output, and would have been invisible on a flame graph (this was before flame graphs).

C is particularly a bigger issue once you consider Amdahl's law. A 20% slowdown in a linear part of the code can show up as a second-for-second slowdown in response times, while a search algorithm that's only a small part of an overall process, or parallelized, you can make it 10 times faster and might only see a 2% improvement in response times. If you avoid allocating more servers, for a new feature, nobody celebrates your achievement. You have to do it wrong the first time for anyone to notice you.

Re:14,000x Speedup (2015) by kadoban on Tuesday October 13, 2020 @12:11PM (#24766899)
I'd argue that none of that is the hardest part of programming, or at least what I'd focus on in terms of what comes up the most and what effects users and developers and suits the most.

Judging by those, the most important hard parts are around planning and estimating work, and correctly understanding when those make no sense, and in validating code for correctness, especially over time.

If we ignore importance and just go with what's the hardest single task: naming things.

Re:14,000x Speedup (2015) by hinkley on Tuesday October 13, 2020 @01:38PM (#24767810)
First, there is no one answer here. When we specialize we take on some 'hard parts' and delegate other hard parts to other people. Civilization is predicated on you and I having different definitions of 'difficult'.

But I think they're of a piece. All of these things are "meatspace" problems. We are constantly fighting the temptation to try to intellectualize the whole process of making software because the center of the problem is trying to interact with a machine. Some don't fight that temptation at all.

You see this problem when people fight automation because they expect everyone to execute a manual process perfectly every time, even when the consequences of failure are very high. They insist that everybody white-knuckle everything and think less of you if you don't agree. They victim-blame. When they're the founding or oldest surviving members of a project, you're gonna have a bad time. People who could fix the problem move on to other jobs.

Naming things is really the same class of problem. A bad name calls to mind assumptions that are not relevant, and you are in constant danger of making category errors every time you think about that part of the code. A bad name becomes a sort of attractive nuisance.

The C problem is a matter of motivating people to do the right thing. Because it's difficult to spot, it's an invisible sin. It rarely comes up in code reviews, so nobody will call you out on it, nobody will make you fix it, finding it after the fact is daunting, and the only people who will care (eg sales) are so often the source of other problems that pleasing them is almost a character flaw. If performance is a feature, then constant time regressions are one of our worst games of whack-a-mole (behind security and internationalization, maybe ahead of sane logging).

[ETA:] I'm just a weirdo who likes to tilt at some kinds of problems I find hard, instead of dumping them on someone else.

Re:14,000x Speedup (2015) by karmakaze on Tuesday October 13, 2020 @05:17PM (#24770416)
The real problem with naming things is that the wrong 'things' have been isolated, if there was a clear understanding of what was being isolated and why the naming part would be easy(er).
Re:14,000x Speedup (2015) by SAI_Peregrinus on Friday October 16, 2020 @09:59AM (#24800866)
There are two hard problems in computer science: naming things, cache invalidation, and off-by one errors.
Re:14,000x Speedup (2015) by amenod on Tuesday October 13, 2020 @03:06PM (#24769005)
> On one project I got a 2x improvement in overall performance by fixing issues that weren't visible in the perf output, and would have been invisible on a flame graph (this was before flame graphs).

I assume you mean that these improvements would not be visible on a flame chart because they were not in perf output? (assuming one was built from the other?)

Flame graph by definition shows where the time is spent and is just a (great, imho) visualization of this data. Some people seem to have a beef with it, but their issues are invariably tied to the way the original data is gathered.

Re:14,000x Speedup (2015) by hinkley on Wednesday October 14, 2020 @08:36AM (#24775790)
This got longer than I intended, but that just illustrates that the rabbit hole is deeper than many people are willing to go.

The data can be wrong in a number of dimensions. In general, code that gets called the most sometimes get underreported. Look at invocation counts. Ask questions.

One, they can clear the CPU cache, causing sibling functions to be overreported (one of many sources of how changing a slow function may bring less of an improvement than expected). This shows up strongest when I‘ve gotten a 10% runtime improvement from fixing a function reported as 5% of total time, or a 10x reduction in time from removing half the calls to a remote service.

Two, duplicate or idiomatic code will be scattered across different parts of the code stack, reducing the apparent magnitude of a pattern of logic below the threshold of attention of most people. Code that is in four places may represent 5% of total time and not get looked at, even if it’s an easy fix. The nickels and dimes add up quickly.

Three, functions that operate near the limits of the clock resolution will be counted properly but the cumulative timing rounded down, again putting it below the noise floor for most people. I’ve made a lot of hay re-sorting the results by invocation count and benchmarking changes to functions that never hit the top 20 list.

And last but not least, functions that create but don’t destroy their own memory allocations end up shedding timing that gets picked up by the recipients, homogenizing the timing graph. In particular in GCed languages, a function that is called in a loop that exhausts most but not all of the free heap will invariably end up stalling out in the next phase of a large calculation.

With all four of these, there are several failures of imagination I commonly saw. A flat timing graph is taken as evidence that it is time to stop optimizing, even if the target improvement has not been met. When the “tent poles” are even, getting people to care how tall they are is challenging. Few people will make six changes to the code to achieve a 10% speed up. The Rust compiler may be the first time I’ve witnessed anyone else brag about a 1% performance gain, other than me. They either don’t do it, or they apologize for achieving so little. 10% is 10%, and I don’t care where you found it, if your code quality is high enough. And perhaps most importantly, speed improvements are multiplicative, not cumulative. Use a time budget the way game devs do. If an interaction takes 10x as long as your target, every method that takes 0.5% of current run time represents 5% of your target. This is, in particular, how you spot duplicated slow code. You ignore them at our peril.

Particularly in the era of QA cycles, using a “zone defense” (optimizing one module at a time, instead of going after tall tent poles) netted a higher rate of return per hour of labor and a much larger cumulative improvement, on its own merits and by increasing the budget allotted to perf. It seems concentrating the changes in one area at a time decreases optimization fatigue. On two projects I kept that initiative alive for more than two years, and I was the one that gave up because I had cycled around the entire system and was finding few things to correct (you only learn new tricks so fast, and they go asymptotic eventually). Everyone came to expect every release to be a bit faster than the previous, and I got feedback that this narrative increased sales, and manager buy-in. People will take a chance on you when they like where you’re going, even if you haven’t gotten there yet. Narrative matters, if they trust you, and usually you have to earn it.

Re:14,000x Speedup (2015) by amenod on Thursday October 15, 2020 @12:36PM (#24790538)
Yes, I agree with you - I just don't see that as a failure of flame charts.

You still need to understand how the data was gathered and what it really means. It is also true that flame charts are more useful on projects that are not yet heavily optimized; they clearly show the parts that are very slow compared to others. And when you don't see anything else that can be optimized, it doesn't mean that everything is optimal - the limit is imagination (and knowledge), not the problem space.

Re:14,000x Speedup (2015) by arethuza on Tuesday October 13, 2020 @12:13PM (#24766934)
Out of interest, did they say what they thought the hardest part of programming is?
Re:14,000x Speedup (2015) by mynegation on Tuesday October 13, 2020 @12:24PM (#24767046)
Just one hardest part? Could be naming things and off by one errors.
Re:14,000x Speedup (2015) by joshuak on Tuesday October 13, 2020 @12:43PM (#24767252)
... and cache invalidation
Re:14,000x Speedup (2015) by nullsense on Tuesday October 13, 2020 @05:58PM (#24770814)
...and off by one errors
Re:14,000x Speedup (2015) by z3t4 on Tuesday October 13, 2020 @12:58PM (#24767418)
What is the C constant?
Re:14,000x Speedup (2015) by vonmoltke on Tuesday October 13, 2020 @01:30PM (#24767726)
If I understand hinkley's point correctly, it's the constant multiplier (and, in some cases, lower-order terms) that conventional complexity analysis handwaves away as irrelevant because it only looks at the limit as input size goes to infinity.
Re:14,000x Speedup (2015) by naruvimama on Tuesday October 13, 2020 @01:31PM (#24767737)
I guess the op meant the C as in

Total time = nX + C

No matter how much you optimize X (n here is for instance the number of items), if C is significant then it matters. It is usually harder to optimize the constant C in the OP's experience.