7 ms·
Well, then that’s not the original use case anymore, and it’ll have to be re-engineered. In the meantime it may have been used for years and the perf difference
by qzw 6y ago
Well, then that’s not the original use case anymore, and it’ll have to be re-engineered. In the meantime it may have been used for years and the perf difference may have saved many developer-years collectively across its user base. Surely you’re not suggesting that the compiler developers should be prematurely optimizing for future use cases that they may not even have envisioned.
- rubber_duck 6y agoAvoiding leaks is not optimisation, it's a matter of correctness - not freeing memory is an optimisation based on a very shortsighted assumption that is not practical for any new language (modern languages are expected to come with language server support)
- random314 6y agoYou have not provided any refutation to the OPs argument.
- jashmatthews 6y agoWhy do you say that? Even if you call free immediately after a piece of memory is no longer needed, malloc won’t release that immediately anyway. If this is incorrect, then every modern malloc implementation is incorrect.
- jpitz 6y agoCorrectness means adherence to the spec, not some contrived absolute truth.
- viraptor 6y agoBut the spec usually has some implicit assumptions. Usually it's "app doesn't leak memory" in the same way nobody explicitly specifies "result of an addition of natural numbers should match ...". We don't go around saying "oh, you didn't want modulo 5 arithmetic? You should've put that in the spec, not rely on some contrived absolute truth".
- jpitz 6y agoOkay, but we're talking about an application, a piece of software who's primary intention is to run for a short period of time, parse a text file and transform it. It will be ran many many many times a day by developers whose time is expensive. Language servers are a very new concept in terms of being part of the day-to-day tool chains for most developers. Trading garbage collection for compile time was absolutely a winning strategy for compiler writers. It made them money.
- viraptor 6y ago"We made dodgy choices to be competitive" is a valid explanation. They don't start being dodgy when new use cases come around and technical debt bites you in the butt. I see not freeing as a clever bug/workaround with nice positive side effects. Not as a clever solution.
- pjmlp 6y agoLanguage servers go back all the way to Xerox PARC workstations and Lisp machines. C++ had its very first language servers via Lucid's Energize C++ and Visual Age for C++ v4. Here is the 1993 video and related paper from Lucid. https://www.youtube.com/watch?v=pQQTScuApWk https://www.youtube.com/watch?v=pQQTScuApWk http://www.dreamsongs.com/Cadillac.html http://www.dreamsongs.com/Cadillac.html And some information regarding VA, unfortunately most is missing from online world. https://www.ecomstation.it/pido2/home/esterni/vac40os2.pdf https://www.ecomstation.it/pido2/home/esterni/vac40os2.pdf (codestore) http://www.edm2.com/index.php/VisualAge_C%2B%2B_4.0_Review http://www.edm2.com/index.php/VisualAge_C%2B%2B_4.0_Review It is also why Delphi, VB and C++ Builder were already such a pleasure to use versus the Makefile and vi world of UNIX.
- jashmatthews 6y agoIt’s usually the opposite! Correctness work usually has the implicit assumption of infinite memory.
- nitwit005 6y agoBut the memory doesn't leak, it gets freed when the program exits. The user doesn't care that each allocation is paired with another call to free it up. They just care if the program runs quickly and doesn't use too much memory overall.
- nelhage 6y agoWe used precisely this optimization in [sorbet](https://sorbet.org https://sorbet.org), a brand-new type checker for Ruby, which also contains a high-performance LSP server. We wrote the entire thing (and tested, using ASAN and fuzzers and other techniques) to avoid leaking memory, and then strategically inserted [the equivalent of a rust `mem::forget`](https://github.com/sorbet/sorbet/blob/0aae56e73c7680ec6053b3d70df26cd3322839c2/main/realmain.cc#L671-L677 https://github.com/sorbet/sorbet/blob/0aae56e73c7680ec6053b3...) into the end of the `main` driver during standalone mode, to avoid calling those destructors when we're about to exit anyways. This optimization is definitely still relevant for new systems today.
- pdimitar 6y agoI am suggesting they apply good practices. I'd never imagine that compilers were actually doing what was stated -- sounds awful. I understand it's tradeoffs and we all have real-world limitations to contend with -- but again, of all the corners that could be cut that's exactly the one I didn't imagine they would. Nasty.
- rcxdude 6y agoDeallocation at the end of a program's execution can substantially add to its runtime, and it's entirely waste. It's a much more common strategy than you might think.
- pdimitar 6y agoYou are right, I indeed didn't know it was that common. But still, in a world where languages and runtimes are also judged by their ability to run in lambda/serverless setups, I'd think this practice will start being obsolete, wouldn't you think? (What I mean is that I imagine that any serverless function that runs in severely constrained and measured environments like the AWS Lambda would gain a significant edge over the competition if it did an eager cleanup. Should allow more of them to work in parallel?)
- folmar 6y agoMost compiler are not designed to run in daemon mode, specifically it's non-issue since their startup is normally fast. And the compiler and runtime are a different thing.
- pdimitar 6y agoI realise that, but nowadays language servers are a pretty normal practice in no small amount of areas.
- smabie 6y agoYou mean like LSP? Why would a compiler and a language server be integrated in the first place? Clearly a LSP server wouldn't use a no-freeing strategy, but there's no reason why it would cause issue with a compiler. A compiler must terminate, assuming parsing isn't turing complete (like Perl) and that the source code is finite. This is why it's okay for it to leak memory.