Best make it so that they understand it. Who "they" is might be dependent on the situation.
Best make it so that they understand it. Who "they" is might be dependent on the situation.
The more specialized or niche certain project areas are, the less likely anyone will ever be reading it directly as a programmer (and those that need to, are often able to disentangle the obscurity). The compromise is a clean interface to otherwise isolated or pure functions.
Often times, this is unfortunately poorly executed or inappropriately assumed. Usually the people who should write clever code are the ones who have experience writing clever code, but almost certainly anyone starting to write clever code is writing terrible code.
Inexperienced folks often write clever code to solve a business need at that time. They create tremendous tech and culture debt. It’s easy to not understand when you’re an IC or line manager, though, that the business could have been severely affected otherwise. I’ll take millions in tech debt opportunity cost and the future morale hit over a failed startup/vertical any day.
Just my 2c in high performance or hardware constrained projects both as an IC, and as various levels of management who’s both inherited mountains of “clever” shit and and built my own directly or indirectly.
You can use naming, formatting and comments where needed to ensure that you and the next person can read and understand it without affecting performance.
Well, maybe sometimes we shouldn’t.
Let’s pick a topical example. Suppose we have a tool used by JS developers, itself written in straightforward JS. Its code is nice and easy to read, and it does the job. However, it takes 5s to process a source tree containing a few thousand lines of code.
Now suppose we could have an alternative version of that tool, written by a skilled developer using a more performance-oriented language, and placing greater emphasis on runtime performance even if it means sacrificing some readability in the source code. This might do the same job in well under a second. As esbuild¹ has shown, this scale of performance improvement is realistic.
Maybe this tool gets run 50 times per day. Then a single developer using it could justify spending about a week writing the faster alternative tool to break even on time saved over five years. (There’s an xkcd² about this that is worth a look if you haven’t seen it before.)
But maybe this tool doesn’t have just one user, it has one million. Then those frequent 5s inefficiencies add up to several hundred users’ entire careers in lost productivity over that same five-year span.
That’s a high price to pay for writing software in a way that is more convenient for developers but less good for users.
For years (literally!) I've been on the lookout for an efficient Javascript blur algorithm. I've attempted to code them myself following various online tutorials, or lift the code from others who seemed to have better insights into various algorithmic approaches than me. Because I struggle with complex mathematical concepts, I've tended to steer clear of code that looks nothing like Javascript.
Then last week I discovered a blisteringly fast gaussian blur algorithm in a GitHub repository[1] which translated work done by some very clever Intel developers[2] into Javascript. I copy-pasted the code on blind trust into my library code, then tweaked more in hope than knowledge to get it to bed in and play nicely[3] ... and it works! 40px radius gaussian blurs over 800x800px images at 60fps (in a 2D canvas - no webgl gets hurt by this algorithm).
I consider myself a well-versed JS coder, yet I've stared at this code until my eyes water: none of it makes sense to me. All I know is that it works by magic, and that makes me happy!
[1] - https://github.com/nodeca/glur/blob/master/index.js
[2] - https://software.intel.com/en-us/articles/iir-gaussian-blur-... - page redirects if you're not logged in
[3] - my tweaked code - https://scrawl-v8.rikweb.org.uk/docs/source/factory/filterEn...
I think I may be able to explain the gist (though not the full details).
It uses an IIR filter, or Infinite Impulse Response filter. This is a digital filter (could be either software or hardware) where there’s a feedback loop from the output to the input. The advantage of an IIR is that it can produce a long output (potentially infinite, hence the name) from a single input. The disadvantage is that IIRs can easily get unstable and hard to work with; hence many (most?) applications use FIRs, Finite Impulse Response, where there’s no feedback and the output is strictly bounded.
It looks like they’re using an IIR tuned to produce a Gaussian bell curve as the impulse response. By feeding each pixel through the filter in sequence, each pixel produces a bell curve and those get blended together, exactly what you what.
So, that tight inner loop consists of reading in the next pixel and blending it with the intermediate results of earlier pixels.
Very efficient on a CPU where you can stream the data through, but it wouldn’t work in an OpenGL shader as that expects to work on each pixel in parallel, not sequentially.
I'm just not sure that's a decision that we often have to make. Is more performant code most of the time also less readable? What about still using JavaScript, still having readable code and getting the execution time to 1-2s?
Also, using another language is probably never the issue except its some weird rarely used language.
But given your scenario: what if changing to the other language and the less readable code keeps other developers from extending the tool, writing plugins and stuff? So what if you have to give up all those contributions from other people?
I don’t think there is a simple relationship between performance and readability, but they aren’t completely independent. Many choices in programming can improve readability but also put a bound on achievable performance.
For example, suppose you choose a programming language that offers a lot of dynamic features at runtime. You might be able to express your ideas more easily using those features. On the other hand, you also need a runtime system to implement those features and that system may have a performance cost.
If you choose a programming language with a high level of abstraction, again you might be able to express your ideas more easily, but you might not be able to control the generated code to ensure that it fully exploits hardware features like parallelism and caching. In some cases, your compiler or interpreter might still do that anyway, depending on the semantics of the language and what the tools can safely infer about your program’s intended behaviour, but this is the classic “sufficiently smart compiler” argument.
An example not involving choice of programming language would be limiting your program to simple, well-understood data structures and algorithms. This makes your program more accessible to developers who are only familiar with the common tools. On the other hand, what if there is a more sophisticated alternative that is faster or requires less space, but the algorithm relies on building and navigating more complicated data structures? What if that alternative isn’t a standard technique that new developers can look up in a textbook, but rather something created after months of work by your own subject matter experts, who have since left the company? What if it is a standard technique, but one that is usually used to solve a different kind of problem, and it happens to be applicable in your current situation because some specific insight about your problem lets you reduce it to the standard one?
What about still using JavaScript, still having readable code and getting the execution time to 1-2s?
These things always depend on context.
With my UI hat on, a 1–2s delay can still be very noticeable to users. For a tool that runs on every save and where the developer is likely to check the results immediately — say, running a test suite, or building and then hot-reloading in a browser — that could still have an impact on each developer’s productivity. If each developer has several tools like that, and there are millions of developers, those little delays still add up to a significant overall drag on the industry.
On the other hand, for a background job that runs only under specific conditions that don’t happen very often, a few extra seconds is probably irrelevant.
But given your scenario: what if changing to the other language and the less readable code keeps other developers from extending the tool, writing plugins and stuff? So what if you have to give up all those contributions from other people?
Well, in this particular thought experiment, you could afford (in the productivity sense) to have a few thousand developers drop whatever they're doing and work full-time on developing your original tool instead for years and you’d still come out ahead. You can teach a lot of people a new programming language and explain a lot of correct but less readable code in thousands of years.
The real point here is that there is often a balance between making things easier for developers and making things better for users. Popular wisdom in our industry says that making things easier for developers is usually the right answer because developer time is expensive, but this is a conceit.
If there are few developers but many users, a little extra cost for developers may create a much bigger gain for users, taken over the groups as a whole. We’ve already been talking about a good example in this discussion.
This isn’t the only situation where developer costs aren’t necessarily the most important factor. What if the development environment is cheap but the runtime environment is expensive? If you have cloud infrastructure and usage-based pricing, maybe improved software performance would mean you could serve results twice as quickly or only need half as much storage. You can just throw more virtualised resources at an inefficient system in the cloud, but your infrastructure bill won’t thank you for it.
Related considerations arise if your software will run on a specialised platform like a supercomputer or a satellite or a tiny embedded medical device. Sometimes you have access to highly specialised but strictly limited resources, and you might not be the only one wanting to make the best use of them. Obviously each of these is a niche application, but there’s lots of software that isn’t web and mobile apps, and those developers also have to make trade-offs between readability and performance sometimes.