| |
| Posted by tchaloupka in reply to H. S. Teoh | PermalinkReply |
|
tchaloupka
Posted in reply to H. S. Teoh
| On Wednesday, 17 November 2021 at 02:32:21 UTC, H. S. Teoh wrote:
> With a GC, you instantly eliminate 90% of these problems. Only 10% of the time, you actually need to manually manage memory -- in inner loops and hot paths where it actually matters.
GC phobia is completely irrational and I don't see why we should bend over backwards to please that crowd.
T
I tell you a story :)
I came from C# so not a GC phobic at all. It's a different mindset compared to hardcore C/C++ devs. (just get the shit done using some of so many libraries out there).
What I liked (and still like) that D allowed me to do is become more low level, more performant, but still be very productive. D code also is ofter much shorter and easier to understood (rust makes my eyes bleed).
GC allows that and is great for. And I must admit that D had broken me in a way that I don't want to use higher level languages anymore. I've learned a lot using D through the years.
BUT:
- have you tried to write a shared D lib used from some other language from multiple threads? I know that you must register/unregister threads in GC, but it just hasn't work for me reliably in any way and you would have to track the lifetime of the thread in the calling language - not pleasant experience at all, no tutorials of how to do that properly that actually works - it's some years old experience now so maybe something has changed
- as GC is
stop the world kind, only way to make it to not intervene with you and still use it in other places is make a thread (with a @nogc function) that is not registered in the GC and make some own mechanism to exchange data between GC and @nogc threads (as std.concurrency won't help you here)
- GC won't magically stop the leaks. Nowadays one want's to have a long running service that just works. But try that with a 'flagship' vibe-d framework and you probably get this experience
- I don't like much when GC.stats reports something like: 239MB free from 251MB used memory that is a lot of unused space in a microservice world (and we had a cases when OS just OOM killed the service as it just grows indefinitely regardles there is a majority of free space in GC - as GC.stats says)
- and now figure that out -> after that experience I would rather use
asan than GC with no tools helping to figure that out
- we have somehow managed to set GC properties in a way that it doesn't grow that much and get rid of a lot of small allocations, but with a cost you wouldn't expect using the GC
- one of the cases that caused a lot of unnecessary small allocations was something like this
row["count"].as!long when reading the columns from a database. Seems like a totally normal way right? But there is much more to it. As it (dpq2 library) uses libpq internally that addresses columns by their index, it uses C method with char* column name to get it and so is using toStringz that allocates, for every single use of that column for every single row being read. You can imagine where it goes handling some complex queries on thousands of rows. And that is not something that a programmer like 'original me' wants to care about, he just wants to use the available libraries and get the work done, that is what GC should help with right?
- there are leaks caused by druntime bugs itself (for example https://issues.dlang.org/show_bug.cgi?id=20680)
After those and some other experiences with GC I just became a bit GC phobic (I'm ok with GC for CLI tools, scripts, short running programs, no problem with that there) and try to avoid it as much as I can. But when you want to get shit done you can't write all on your own, but use the libraries that get you there with no much hassle between.
Overall my 2 cents on D state:
- druntime relies too much on the GC
- no Fiber usable in @betterC or @nogc
- no Thread usable in @betterC or @nogc
- etc.
- I just think that basic blocks we built on should be as low level as possible to be generally usable
- druntime and phobos has many
extern(C) or normal functions that aren't @nogc albeit they can be (but is's getting better with each release thanks to various contributors that cares as much as at least report it) - but look at codebases of mecca or vibe-d where they use their own extern(C) redefinition due to this, or mecca has assumeNoGC template to workaround missing @nogc attribute
- std.experimental.allocator
- still in experimental
- not usable in
@betterC
- shouldn't generally standard library interface use the allocators so that caller can actually choose the way it allocates?
- preview switches that would stay in preview forever (ie
fieldwise )?
- no
async /await - it's hard to find a modern language without it, D is one of them and there doesn't seem to be any interest in it by the leadership (it would deserve a workgroup to work on it)
- but I'm afraid even if it would potentially be added to the language it would still use the GC as GC is great..
- pure tooling compared to others - I'm using VSCode in linux (sorry I'm lazy to learn vim in a way I'd be effective with it), it somewhat works, but code completion breaks too often for me (I'm used to it over the years, but I can imagine it doesn't look good to newcomers)
- dub and code.dlang.org doesn't seems to be too official, and being cared about
- it's hard to tell anyone that GC in D is fine when you look at techempower benchmark and searching the vibe-d (or anything in D) somewhere up where it should be and isn't (event other GC languages are much higher there)
betterC seems to becoming an unwanted child and is a minefield to use - see bugs
- I think there are 2 sorts of group in D community - one more low level that won't like to use GC much, and GC 'likers', for whom GC is just 'good enough'
- I'm afraid that there can't be consensus of what D should look as those groups has different priorities and points of view
- preferred memory model differs for them too and I'm not sure if it's possible in D to make both sides happy (and without breaking changes)
- most libraries on code.dlang.org are high level, and mostly when you want to use
betterC or avoid GC, you are on your own. That is a problem when you just want to use some component and be done (if there is no C alternative or it would mean to write a more idiomatic wrapper for it).
|