Search Explore
    • mike_hock · 3 days ago

      Zero-Copy in Go: Why magic is an antipattern, and: performance is observable behavior.

      • sanxiyn · 3 days ago

        What would you prefer?

        I do think it is criminal this is not documented (https://pkg.go.dev/io#Copy), but I think io.Copy is fine as an API.

        • arccy · 3 days ago

          it is documented by saying it calls ReadFrom or WriteTo

          • sanxiyn · 2 days ago

            Sure, but it could be more explicit. See Rust for how it should be done.

      • throwrioawfo · 3 days ago

        Ugh, AI slop writing.

        • drivebyhooting · 3 days ago

          Definitely written by codex.

          • badc0ffee · 2 days ago

            The lack of apostrophe in "dont" makes me think at least part of it was written manually.

            It's also a totally readable article, really.

        • joaohaas · 3 days ago

          Interesting premise for a post, but I had to stop midway due to the AI slop writing adding meaningless information.

          • inigyou · 3 days ago

            This is almost like the expression problem. Copy is a new operation, and you introduced a new type, thus creating a new grid cell nobody from either side could have reasonably known about - except for the fact Copy is in the standard library so you could have known about it but not done anything.

            • drivebyhooting · 3 days ago

              How is the byte counting reader supposed to work in user space without putting the buffer in user space? The article claims there is a way but I want to see what is meant by counting bytes in that case.

              • flakes · 3 days ago

                sendfile(2) and io.ReaderFrom both return the number of bytes transmitted. The issue is that users are unaware of (or forget about) the optional interface upgrades and fail to define all the methods required for interface upgrades on their wrapper structs. You can definitely make a counting reader with a minimal performance loss, but the proper solution is less obvious than it ideally should be.

                • drivebyhooting · 3 days ago

                  Isn’t this a symptom of structural/duck typing where interfaces are not declared? In Java for all its faults this wouldn’t happen because you’d be forced to implement all the interfaces.

                  • flakes · 3 days ago

                    > Isn’t this a symptom of structural/duck typing where interfaces are not declared

                    Yes, essentially duck typing. See https://github.com/golang/go/blob/65504872cbca64d77f45828409...

                    The logic uses a type assertion to safely verify if the value backing the provided io.Reader interface also implements the io.ReaderFrom interface. If it matches, then it will use the more efficient implementation

                        if rf, ok := dst.(ReaderFrom); ok {
                            return rf.ReadFrom(src)
                        }
                    
                    > In Java for all its faults this wouldn’t happen because you’d be forced to implement all the interfaces.

                    I don't think I would go that far. In Java, many libraries make heavy use of the `instanceof` keyword, which is more or less the same as Go type assertions.

                    • pjmlp · 3 days ago

                      Yes, but contrary to Go, if you change an interface it will be a compiler error if additional methods are missing, unless they have default implementations.

                      In Java type assertions are mostly used when writing code pre-generics style, like downcasting from a common subclasse into the actual implementation, not to see if an interface is supported, as it is a given from the type system.

                      • ericpauley · 2 days ago

                        It’s pretty common to type check interface implementations in Go using package-level casts.

                        • pjmlp · 2 days ago

                          I know, it is yet another language hack, just like the iota/const dance, instead of proper language constructs.

                          • flakes · 2 days ago

                            How is a package level interface check a “language hack”? They are straight forward and provide a user the same compile time guarantees as the Java implements keyword.

                            • pjmlp · 2 days ago

                              Because they are a workaround for what should be a language feature in first place, just like on ML languages to type check structural types.

                              • flakes · 2 days ago

                                What exactly isn’t a language feature? Or do you have issues with semantics?

                                    var _ Foo = (*Bar)(nil)
                                
                                The statement asserts that Bar struct pointers are assignable to a Foo interface.

                                I do agree it’s not as clean looking as the Java implements keyword, but it’s already a fairly terse pattern and IMO the inconvenience does not justify introducing new language syntax.

              • sly010 · 3 days ago

                Beware, there are versions of go where sendfile is broken and only sends the first 4k of a file on macos.

                • majewsky · 2 days ago

                  If this is a thing you need to beware of, you should more importantly beware of using a version of Go that's been outdated for over 1.5 years and EOL for nearly a year.

                  Context: https://github.com/golang/go/issues/70000 fixed in 1.23.3 (released 2024-11-06), EOL for 1.23.x was 2025-08-06