Live data from Hacker News

Generics can make your Go code slower

planetscale.com

361–370 of 418 posts

Re: Generics can make your Go code slower

#361

Earlier quoted context omitted.

Java _needs_ lots of GC tuning parameters because you have practically no way of tuning the way your memory is used and organized in Java code. In Go you can actually do that. You can decide how data structures are nested, you can take pointers to the inside of a a block of memory. You could make e.g. a secondary allocator, allocating objects from a contiguous block of memory. Java doesn't allow those things, and thu…

That's the Go party line but not really true. Counter-example: The Go GC is tuned for HTTP servers at latency sensitive companies like Google. It therefore prioritizes latency over throughput to an astonishing degree, which means it is extremely bad at batch jobs - like compilers. What language is the Go compiler written in? Go. This isn't fixable by simply writing the code differently. What you're talking about is i…

> it is extremely bad at batch jobs - like compilers. > What language is the Go compiler written in? Go.

I do not see what are you trying to say?

The Go compiler is plenty fast in my experience, especially compared to say `javac`. The startup time of `javac` (and most java programs) is atrocious.

Re: Generics can make your Go code slower

#362
post #359
post #344

Earlier quoted context omitted.

It needs one to understand Go modules and how they change across language versions.

Go module are easy to use, compiling is even more simpler: go build .

If you say so,

"HERO: On the Chaos When PATH Meets Modules"

https://cs.nju.edu.cn/changxu/1_publications/21/ICSE21_02.pd...

Re: Generics can make your Go code slower

#363

Earlier quoted context omitted.

From a conceptual point of view, I agree, but... in practice, stacks are incredibly cheap. The entire set of local variables can be allocated with a single bump of the stack pointer upon entry into a function, and they can all be freed with another bump of the stack pointer upon exit. With heap allocations, even with the simplest bump allocator.. you still have to allocate once per object, which can easily be an orde…

> you still have to allocate once per object Why can’t you bump once to allocate enough space for multiple objects?

You can’t do it that way because each object has to have its own lifetime.

If you allocate them all as a single allocation, then the entire allocation would be required to live as long as the longest lived object. This would be horribly inefficient because you couldn’t collect garbage effectively at all. Memory usage would grow by a lot, as all local variables are continuously leaked for arbitrarily long periods of time whenever you return a single one, or store a single one in an array, or anything that could extend the life of any local variable beyond the current function.

If you return a stack variable, it gets copied into the stack frame of the caller, which is what allows the stack frame to be deallocated as a whole. That’s not how heap allocations work, and adding a ton of complexity to heap allocations to avoid using the stack just seems like an idea fraught with problems.

If you know at compile time that they all should be deallocated at the end of the function… the compiler should just use the stack. That’s what it is for. (The one exception is objects that are too large to comfortably fit on the stack without causing a stack overflow.)

Re: Generics can make your Go code slower

#364
post #328

Earlier quoted context omitted.

Go does have some of these features: annotations, enums, JFR. They're just built for features of Go rather than Java. They're not the same but perform similar roles for the Go language. Error handling is subjective but I'm not going to disagree it could use some help. Same with Go's GC in certain situations but nothing I've coded has needed more. All that said, what makes your list any different than a similar list c…

> They're just built for features of Go They're inferior, and do not cover the same grounds (e.g. "enums" in golang are just integer constants, you can't code gen using golang tags, JFR is way way more comprehensive than anything that golang has etc.) The GC selection, JIT, and hot swapping/reloading are features that do not exist in golang, and we've seen what hoops people have to jump through when they face issues…

Why does golang need JIT when it already statically compiles to a non-virtual machine target?

It could probably use some performance optimizations, but JIT would be redundant when it's already compiled.

Re: Generics can make your Go code slower

#365

Earlier quoted context omitted.

> you still have to allocate once per object Why can’t you bump once to allocate enough space for multiple objects?

You can’t do it that way because each object has to have its own lifetime. If you allocate them all as a single allocation, then the entire allocation would be required to live as long as the longest lived object. This would be horribly inefficient because you couldn’t collect garbage effectively at all. Memory usage would grow by a lot, as all local variables are continuously leaked for arbitrarily long periods of t…

> If you allocate them all as a single allocation, then the entire allocation would be required to live as long as the longest lived object.

No, you can copy objects out if they live longer than others. That's how a generational GC works.

Re: Generics can make your Go code slower

#366
post #328

Earlier quoted context omitted.

Go does have some of these features: annotations, enums, JFR. They're just built for features of Go rather than Java. They're not the same but perform similar roles for the Go language. Error handling is subjective but I'm not going to disagree it could use some help. Same with Go's GC in certain situations but nothing I've coded has needed more. All that said, what makes your list any different than a similar list c…

> They're just built for features of Go They're inferior, and do not cover the same grounds (e.g. "enums" in golang are just integer constants, you can't code gen using golang tags, JFR is way way more comprehensive than anything that golang has etc.) The GC selection, JIT, and hot swapping/reloading are features that do not exist in golang, and we've seen what hoops people have to jump through when they face issues…

Enums in Go are inferior but that doesn't stop you from using them in the same way.

Of course you can code gen using Go's tags. It's done all the time.

As already pointed out, Go has the JFR it needs, not what Java has.

Go doesn't need a JITter.

Go isn't perfect, but neither is Java or C#. Go code is known for being maintainable and easy for newcomers to read so your last line applies to Java more than Go. But it seems like you want to hate Go. Why?

Re: Generics can make your Go code slower

#367
post #43

Earlier quoted context omitted.

In practice, it's used as an alternative to python and ruby and nodejs. It can't fully do what Java or C# do.

> It can't fully do what Java or C# do. I am curious, what all stuff it cannot do?

Mostly stuff related to tooling and environment because unlike Java, it hasn't been around for two decades for people to patch its weaknesses with workarounds.

Re: Generics can make your Go code slower

#368

Earlier quoted context omitted.

You can’t do it that way because each object has to have its own lifetime. If you allocate them all as a single allocation, then the entire allocation would be required to live as long as the longest lived object. This would be horribly inefficient because you couldn’t collect garbage effectively at all. Memory usage would grow by a lot, as all local variables are continuously leaked for arbitrarily long periods of t…

> If you allocate them all as a single allocation, then the entire allocation would be required to live as long as the longest lived object. No, you can copy objects out if they live longer than others. That's how a generational GC works.

I edited my comment before you posted yours. Making heap allocations super complicated just to avoid the stack is a confusing idea.

Generational GCs surely do not do a single bump allocate for all local variables. How could the GC possibly know where each object starts and ends if it did it as a single allocation? Instead, it treats them all as individual allocations within an allocation buffer, which means bumping for each one separately. Yes, they will then get copied out if they survive long enough, but that’s not the same thing as avoiding the 10+ instructions per allocation.

It’s entirely possible I’m wrong when it comes to Truffle, but at a minimum it seems like you would need arenas for each size class, and then you’d have to bump each arena by the number of local variables of that size class. The stack can do better than that.

Re: Generics can make your Go code slower

#369

Earlier quoted context omitted.

> If you allocate them all as a single allocation, then the entire allocation would be required to live as long as the longest lived object. No, you can copy objects out if they live longer than others. That's how a generational GC works.

I edited my comment before you posted yours. Making heap allocations super complicated just to avoid the stack is a confusing idea. Generational GCs surely do not do a single bump allocate for all local variables. How could the GC possibly know where each object starts and ends if it did it as a single allocation? Instead, it treats them all as individual allocations within an allocation buffer, which means bumping f…

When you allocate objects individually it looks like this:

    object_a = tlab
    tlab += 8
    check tlab limit
    object_b = tlab
    tlab += 8
    check tlab limit
When you allocate as a single allocation it looks like this:

    object_a = tlab
    object_b = tlab + 8
    tlab += 16
    check tlab limit
What about that do you see as impossible?

> How could the GC possibly know where each object starts and ends if it did it as a single allocation?

As above.

Re: Generics can make your Go code slower

#370

Earlier quoted context omitted.

> A good portion of production outages are likely related to cascading failures due to too long GC pauses, and a good portion of developer time is spent testing and tuning GC parameters After 14 years in JVM dev in areas where latency and reliability are business critical, I disagree. Yes, excessive GC stop the world pauses can cause latency spikes, and excessive GC time is bad, and yes, when a new GC algorithm is re…

> After 14 years in JVM dev in areas where latency and reliability are business critical What sort of industry/use cases are we talking here? There is business critical and mission critical and if your experience is in network applications as your next paragraph seems to imply then no offence, but you have never worked with critical systems where an nondeterministic GC pause can send billions worth of metal into the…

Um, how did you derive from this conversation that the "outages" in question were about space missions failing?

Curious, and a tad confused.

Post reply on HN