Live data from Hacker News

Show HN: Lockless Ringbuffer Built with Go Generics

github.com

1–10 of 23 posts

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#2
Please excuse my ignorance, but here goes:

Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.

Now, I also don't know what a ring buffer is, so perhaps this is the perfect time for someone very generous to explain to me what a ring buffer is, why generics are what enabled this and how on earth it's multiple times faster than channels, which have been a first-class primitive in Go since the beginning (and should therefore have had the living daylights optimised out of them...)

Many thankings :)

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#4

Please excuse my ignorance, but here goes: Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.…

A memory bound queue and by making use of generics, it has more performance due to having one indirection less per element and being able to store all of them in a continuous memory segment.

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#5

Please excuse my ignorance, but here goes: Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.…

I won't go into super much detail, but think of generics as functions over types that generate new types based on type inputs (gross oversimplification). Comparable to functions that take value and return values, also it happens before your program runs (during compilation/build time).

A ring buffer is just a normal buffer, except that when it "runs out" of space instead of overflowing or returning an error, it "loops back" on itself, and starts writing from the start. You can still grow it, if needed.

The nice thing about generics here is that it allows you to have a RingBuffer[string], RingBuffer[int], and RingBuffer[MyType] without having to implement them separately. The compiler will even take care of memory sizing/layout, and all the other razzledazzle.

As for performance, it's not fully related to generics, but a sibling comment explained the implementation detail and how it affects performance.

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#6

Please excuse my ignorance, but here goes: Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.…

if you have not known what a ring buffer is, may I suspect you to be a developer who taught yourself?

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#7
post #5

Please excuse my ignorance, but here goes: Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.…

I won't go into super much detail, but think of generics as functions over types that generate new types based on type inputs (gross oversimplification). Comparable to functions that take value and return values, also it happens before your program runs (during compilation/build time). A ring buffer is just a normal buffer, except that when it "runs out" of space instead of overflowing or returning an error, it "loop…

Thank you for the information. Much appreciated!

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#8

Please excuse my ignorance, but here goes: Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.…

if you have not known what a ring buffer is, may I suspect you to be a developer who taught yourself?

I certainly am, yes. Spent about 12 years in the wrong career and then realised my love for programming (after a lifelong love of computers. Not sure how I missed that...)

I started with Python (and Kivy). Then went on to Go (which felt like a revelation over Python. For me, anyway). Along with that came JS, HTML, CSS and React.

Because of Go, I had become prejudiced against interpreted, dynamically typed languages. But over time I actually came to quite like JS. If wielded correctly, it can be very quick to get stuff working in JS and now I think either kinds of languages have their merits. Though, admittedly, React still eludes me. It feels incredibly confusing to me.

My next port of call will probably be something like Rust, but I have a product that takes up all of my time, so it's a bit tricky to find the time to catch up on my CS learning.

There is probably nothing that can replace a full-on university education in CS, but I'm not sure when or where I'd fit that into my life (I have a degree and thus know what it takes). I really hope to be able to do as much of that education on my own, however.

Any tips or hints welcome!

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#9
post #4

Please excuse my ignorance, but here goes: Been a Go dev for almost 3 years now. I am basically shitting myself over the prospect of all the Go code out there turning from something I understand, to something riddled with generics, of which I have no concept whatsoever. I've built some pretty complex stuff entirely without them and never felt there was anything missing, but maybe I just never knew what I was missing.…

A memory bound queue and by making use of generics, it has more performance due to having one indirection less per element and being able to store all of them in a continuous memory segment.

Thank you, much appreciated!

Re: Show HN: Lockless Ringbuffer Built with Go Generics

#10
atomic.AddInt32 feels a lot like locking to me. You end up with a write barrier and all the associated consequences, so you can kill throughput (in a way that is more difficult to notice in the profiler, though you'll probably notice it when it's a problem if you ask pprof for a line-by-line profile).

sync.Mutex.Lock is implemented like this:

    func (m *Mutex) Lock() {
            // Fast path: grab unlocked mutex.
            if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {
                    if race.Enabled {
                            race.Acquire(unsafe.Pointer(m))
                    }
                    return
            }
            // Slow path (outlined so that the fast path can be inlined)
            m.lockSlow()
    }
lockSlow is, of course, a bit more complicated.
Post reply on HN