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

Modern GC doesn't even preclude the possibility of developing a no-lag UI. You just have to be very careful with how you manage your data so that you don't get hit with more heavy-handed collection mechanisms (i.e. large gen2 cleanups in .NET).

Small and short-lived class instances (more ideally structs) are the key to success with low-latency applications in most GC'd languages. If you are only touching gen0/1 in a .NET5 app, you will probably find the GC impact to UI latency to be negligible. In .NET, avoiding gen2 allocations is pretty easy. The biggest thing is replacing every byte[] with Stream as feasible, so you don't send objects directly to LOH (gen2). I believe the LOH threshold for byte[] is lower than the published limit of 85k, but I cannot recall the specifics (might be closer to 10k). Regardless, you really shouldn't be holding onto chunks of memory that large if you can ever avoid it. In some cases you can cheat. Pass around the path/id to a file and then stream it from disk at the very last possible moment (i.e. copy a FileStream direct to the HttpContext.Response.Body stream). If you absolutely must allocate large objects, try to reuse them as much as possible. Act as if anything entering gen2 is in memory forever, because with enough LOH fragmentation, it might as well be.

UI is one thing, but real-time process control is a wholly different animal. If you want to write a PID in a GC language, you better be prepared to eschew any notion of allocation in the process under collection. Even if you don't allocate, there are runtime components that still will, so you will almost always have some minimum amount of noise to contend with. That said, if you only need to run a PID loop at ~10khz (100uS loop delay), you probably wont have any issues. Just make sure you put the PID loop on a high-priority thread and care for its surroundings gingerly. A Raspi4+ is actually an amazing platform for this sort of thing.



I suspect Go's GC would be particularly well-fit for this kind of application considering it typically runs in <1ms with no exceptionally large pauses (except perhaps in pathological cases).

Like C#, Go has value types, so controlling allocations should be pretty straightforward.


I had the same thought, it probably wouldn't even interfere with their stated goal of running at 144fps (and of course there would be more Go code analysis libraries available in the Go ecosystem).

I could imagine plenty of other reasons to go with C++ though - there's still going to be a higher performance ceiling, maybe they plan to support languages other than Go, maybe they want a minimal file size compiling to WASM or to use specific C++ libraries etc. It would be interesting to see the original author's thinking behind it, on the website it's mainly comparing C++ to web technologies.


The Micro [0] editor is written in Go as well, which I was surprised by. It's a tidy piece of software, usually install it to replace nano.

[0] https://github.com/zyedidia/micro


I've written a $SHELL in Go which implements a lot of the same features one requires from an IDE such as low latency keyboard input, events subsystem, syntax highlighting, syntax completion, auto-completion suggestions (popups), etc and all of which needs to be context sensitive. So it's definitely possible to write an IDE in Go.

I'd wager the biggest hurdle to writing an IDE in Go isn't the language but rather the lack of mature graphics library bindings. I've seen some attempts at building GUI toolkits in Go but it's fair to say the language's strong points are still firmly in CLI and backend web development domains.


Gio is a very strong contender for GUI in Go.

https://gioui.org


> I suspect Go's GC would be particularly well-fit for this kind of application considering it typically runs in <1ms with no exceptionally large pauses (except perhaps in pathological cases).

Lol.

" 30% of CPU cycles were being spent in function calls related to GC. " https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i...


The raw CPU time used doesn't really matter if it doesn't cause the UI to block. It does for server applications; needing 30% more cores costs 30% more money, which you could use for something else. But for tiny programs that run on your workstation, using 1.3% CPU doesn't cost more than 1% CPU.

You do have to watch out for the case where you can't use all the cores, and GC is blocking actual computation the user wants to perform.

(Also, you're at about 4000 cores when saving 30% buys you another developer. So you have to think about when the right time to unlock that money is, and how much it costs to unlock.)

I've been writing a game in Go. The GC doesn't prevent me from getting a smooth 360 frames per second. 1ms is a substantial pause, but isn't even a missed frame.


> But for tiny programs that run on your workstation, using 1.3% CPU doesn't cost more than 1% CPU.

Especially considering that text editor state changes are dependent on user interaction—it’s not like a video games where the state changes continuously.


The focus on framerates isn’t to account for changes as the user is typing, but rather scrolling. When scrolling through text, is it smooth? Does it tear? For me, that’s what I see when a text editor refers to framerates.


Even still, that constitutes a user event, and not even one that changes the model. Those events presumably come in on the order of tens of milliseconds, so I wouldn't expect this to be a garbage collection problem?


Just as another data-point, java now has ZGC and Shenandoah low-latency GCs that basically sacrifice some throughput for better latency (read barriers instead of write), but the former can already achieve <1 ms global pauses, which is shorter than what the OS scheduler itself can cause. Of course one should never “spam” the GC needlessly, but it does work for up to quite big heap sizes.


ZGC is a very compelling option for applications that get periodic restart opportunities (or are of the cruise missile guidance computer variety).

In places where you have to use reference types, sometimes you can allocate everything you should ever need up-front and then pull from that pool of pinned instances throughout the day. Pre-allocating all of your required memory can provide more deterministic outcomes.


Why only with periodic restarts? Does ZGC accumulate permgen garbage that is never collected?


I don’t think that’s the case at all - that would be a memory leak and considered a bug.

The JVM does have a “do nothing GC” for short lived apps, where not collecting is ok.


Soft real time GCs do well enough to replace C++ with Java in battleship and ground control missile targeting systems, as PTC, Aonix and Aicas have been doing for years.

A frame drop causes little more hazard than just an unhappy gamer.

Speaking of which, many keep forgetting that Unreal C++ and Blueprint make use of GC.


I would contend that 10kHz is pretty fast for a control loop thats doing anything complicated in a Garbage Collected language on a non real-time OS. The later issue being some what of a bigger issue than the GC. You CAN do it... some of the Basic linux real time stuff helps the situation a lot.

In .NET you can also change the GC policy at the thread level which can help a lot.

Pool Allocation (long held chunks of memory that can be manually repurposed) can help a lot, since you can write custom Pools where the Gc never knows it needs to clean up. It is a useful tool when you have big chunks of memory that need to be manipulated at a high rates.

I would say from experience that 500Hz-1kHz is a more reasonable loop time


I can write basically instant local electron code. I've never seen anything close to problematic GC. Maybe other people have issues with their app responding in 5 instead of 1ms?


Often the difference is between small personal projects where performance can easily be kept under control, whereas large production products, that have to handle all the edge cases, accessibility, work on many platforms, etc etc can be quite a bit more complex, require more people working on it, and performance gets harder to keep under control. That last 10% to can be 90% of the complexity and work.

Text editors, especially with language aware features, are far from simple.





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

Search: