Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I really do think curiosity is the most important bit out of all this.

If I see some bit of our code doing something a bit odd, I'm nosy, I'll go and look why. Why does one of our classes use an IDisposable? Why is that property using a custom class? Why is that code using async/await when it looks like it should take nano-seconds?

If it's for a good reason, you'll have invariably found a gotcha, or gained a little more knowledge about the domain you code works in.

But surprisingly often you'll find that it's for a bad reason, or an outdated reason, or someone not really understanding how the functionality they're using works.

In the early days of a language/framework especially, when people really don't understand how it really works, what you see is a lot of cargo-cult code. Doing without understanding. .Net, Jquery, Ruby, Javascript, Typescript, Node, I've seen it happen many times (and of course done it myself too! I remember making loads of pointless singletons in one project a decade ago).

People do something because they don't have the full picture. They make up totally wrong rules like "If I add IDisposable the GC must work better as I believe IDisposable has something to do with the GC so it can't hurt".

A great example right now, in the .Net world, is people are littering their code with async/await. They can't understand it's making their code worse, not better. They don't understand that the performance gain is almost always negligible, but the code complexity increase is expensive.



Async/Await can definitely increase the complexity of the codebase and make stack traces difficult to interpret (especially if you aren't clear on what is happening under the hood), but if you work on any sort of web-based/distributed system, with lots of back-end database/API calls, the performance gain is hardly negligible.

Sure, you won't see much of a difference in response times, but resource usage gets dramatically better, and with it the ability to scale.

If you're working with ASP.Net and you're not using Async/Await, you're doing yourself a disservice.

If that's not your scenario, well then, yeah, dealing with Async/Await is probably not worth the headache.


I do work on web based systems and I can tell you, without a doubt, that the performance gain is bugger all.

I flatly disagree with you, this is exactly the cargo-cult programming I'm talking about.

You're thinking about it totally wrong. Async/await is useful if you have a million pipes, but need 2,000,000. Thats millions of requests per second. Virtually no ASP.Net programmer has that need. They usually need 10 or 20 pipes per second, but they need really, really fat ones. Async/await does not make fatter pipes, it lets you use a single pipe as multiple pipes. But for decades IIS already, by default, supplies loads of pipes.

To make it clear, practically speaking, for virtually every asp.net programmer in the world, async/await is utterly pointless.

It's ok for external website calls. Or something you really need to multi-thread. Like the once in a blue moon tasks.

I work in ASP.Net, I rewrite bad async await code, get rid of it AND improve the performance by orders of magnitude.

Performance problems are almost always, in my experience, SQL bottle necks, bad EF queries or stupid loops. And I have fixed serious performance problems for various businesses. Once in 12 years have I seen IIS running out of threads and that was in 2006 when CPUs sucked. And that was fixed by, amazingly, fixing a bad SQL query.

Littering several hundred 40ms controller calls with asynchronous EF calls that run in 3ms won't make your site faster. Fixing that shitty report that locks 20 tables and takes 2000ms to run causing multiple deadlocks and gets called 5 times everytime someone opens your dashboard because you suck at JavaScript will. Put all the async awaits you want into that bugger, it's still going to screw your site over.

Async/await is a load of utter nonsense for the vast majority of MS customers. And yet now I see people using it for the most asinine calls that clearly do not need it.


Using async/await with desktop GUI apps is basically a no-brainer. Nobody likes applications to randomly lock up and this is a way easier way to solve the problem than the old ones.


Amen to that. Where I work I see people adding await/async all over the place because "performance". So now when you get exception stack traces they are hard to follow or flat out useless.


>They can't understand it's making their code worse, not better. They don't understand that the performance gain is almost always negligible, but the code complexity increase is expensive.

Yeah, sorry, give me an easy to use benchmark for when to decide to use async/await. Knowing when to use Async/await for .NET has been the biggest minefield so far. And yet you see it in ASP.Net and UWP tutorials.


You use async/await when you are doing any sort of IO in an application that needs to be responsive. Example: your ASP.NET thread pool is starved because all your request threads are waiting on IO. It's useless to have those threads waiting there for IO when they could be processing other requests to your server.

You're obviously going to see some overhead from the state machines generated, but that's negligible compared to the gains you'll see in throughput and code readability(compared to the older ways of doing async code).

The same reasoning extends to UWP, don't block your main thread with IO so it can still process input. Obviously there's other ways to handle async in a desktop app, but async/await just make it so much easier to reason about your async code. It looks exactly like you're writing synchronous code.


It's a total nightmare to introduce async into an existing, non-async codebase, so I'm not sure it's a good case for incremental refactoring based on benchmarks.


How do you balance reading code with getting things done? I'm thinking of the "move fast and break stuff" attitude that doesn't seem to leave much room for reading a lot of code. I believe that reading and understanding the code will help you move faster eventually, but you're slower to start. So, how do you know when you've read enough?


I just accept I'm a sprinter when it comes to coding, not a marathon runner. I spend 2 or 3 hours poking the code with a stick, proverbially speaking, reading it, maybe pruning crappy code, maybe faffing around, then bash out the actual code in an hour or two.

I believe what happens is that I form a mental map of the business process and a mental map of the code and then when I eventually come to write something, it just pours out.

Psychologically, it took me a long time to accept that only actually coding 2 or 3 hours a day is fine. For years I beat myself up for being 'lazy'.

EDIT: I mean, it's obviously different if you're just adding an extra column to an existing table or something (usually) trivial like that.


IMHO, the answer to this question is to frequently ask yourself this question as you're working on things. There's no perfect balance, you'll have to make a decision depending on the context and priorities of the moment. It might be ok to gloss over a concept you're unfamiliar with if debugging a production issue and having evidence that the root cause of the bug is in another area of the code altogether. But then make some time during feature development (or when writing a COE about the production issue) to go back to that piece of code and dig deeper into why it's written that way.

To expand on the analogy of the OP with regards to unfamiliar words in a novel, I personally don't look up every single word that I come across when I can get an idea of what it means from the context, but only after I encounter it a few times.


Good points. Thinking about the unfamiliar words analogy I would look up a word if I see it often enough or if it's key to understanding. Knowing if an unfamiliar word is important is tricky though--I can't define the process I use there.


It's clearly a trade-off. I have found that as I gain experience, reading code becomes faster, even for domains that I'm not familiar with, and it's nearly always worthwhile to understand the problem.

Moving fast and breaking things adds to the technical debt. The word debt implies that you will have to repay it (or at least, someone will have to repay it). So moving fast now means slowing down later. Sometimes this is desirable, sometimes not.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: