15 ms·
Go is about to get faster
- oblio 5y agoWhaddya know :-o It turns out that that complex technology was warranted?!?
- mmoll 5y agoMy thoughts exactly. The whole article sounds like: “Whoa, so it really IS useful!” Duh!
- omegabravo 5y agoIt's a shame that this generics debate is framed as a "go programmers discover generics". That has never been the source of contention, and the benefits were noted from the initial discussions of the language before it reached an audience. Like all things it's a trade off. Will you be providing more value with generics, or are other features a higher priority. That's obviously a matter of perspective. Go has many advantages over other languages, and strict typing, generics and raw speed has never been part of that. If those things are paramount for you, there are better languages suitable. Go has been fantastic for the problem space I'm targeting. Fast enough, efficient enough, portable enough, simple enough that hiring is easy. This might not be true for what you work on, but I'm not writing a video decoder.
- threeseed 5y ago> go programmers discover generics It kind of was though. It was endless arguments from Go users that generics aren't needed and can be solved through a combination of cut/paste, code generation or simply dismissing its usefulness altogether. And on the other side the rest of us trying to explain the many, many use cases that demand generics.
- perbu 5y agoI think you're misrepresenting the debate. I've never seen anyone argue that generics aren't a useful concept, but I've seen plenty argue that it isn't worth the cost in incurs. That is a quite a different debate then the one you are outlining.
- oblio 5y ago> plenty argue that it isn't worth the cost in incurs The other "plenty" were arguing that it was worth the cost. So color me surprised that this side was right.
- jonathanstrange 5y agoThere is no such thing as being right in such matters. Simplicity vs. expressivity is always a subjective trade-off. Otherwise, Zig could not possibly be a good language or Rust would obviously be a complete failure, for example, both of which seem like narrow-minded things to say. Sometimes more simplicity, sometimes more expressivity is better. It depends on for whom and for which tasks.
- oblio 5y agoGolang competes in exactly the same space as Java and C#. With a small twist, but the same space. That put a huge burden of proof on the Golang designers as the design space had been studied extensively for 3+ decades. And they skirted around that burden of proof for a while, I never liked their reasoning. They could have just come out and said the didn't like generics and don't need them for their use cases. Zig and Rust are in whole 'nother ballgame so there's no point involving them here.
- 13415 5y agoThat's a bit of an old-school language flame war response. It seems obvious that there is no objective criterion for determining when a language is simple enough and when it isn't. Not everybody uses Go for the same hypothetical "design space", and the implicit claim in your post that the same criteria do not apply to Rust or Zig is also dubious, as if they couldn't possibly work as languages in the same "design space." We're talking about general purpose languages. To give you an example, Rust is overengineered and way too complex for my needs, it would seriously hamper productivity. It's important to be aware that other programmers' mileages differs. The bottomline is that it's never fruitful to argue that feature sets that go into "simplicity" do not heavily depend on subjective programmer preferences, their tasks, and the intended application domains. Programming languages are mere tools, nothing else. Choose the one appropriate for your goals.
- cplli 5y agoI think that some of the concerns around generics, (like mine) are based on the over-use of generics. But, I am very happy for the addition of generics as they'll probably do more "good" than "bad". We'll just have to be pragmatic. Edit: Reminds me of this funny video https://youtu.be/-AQfQFcXac8?t=63 https://youtu.be/-AQfQFcXac8?t=63
- hobofan 5y agoNot giving the programmer a choice and forcing them to be pragmatic was one of the main selling points of Go. Allowing generics at all will likely make them seep into he ecosystem over time and destroy part of that value proposition.
- OtomotO 5y agoBeing pragmatic could also mean using generics when appropriate. Not having generics isn't a pragmatic choice per se
- deepsun 5y agoExactly the same can be said about checked exceptions.
- TheMonarchist 5y agoC++ used to have opt-in checked exceptions ("dynamic exception specification"), that were deprecated in 2011 and removed in 2017. That the once standard feature was removed from C++ speaks a lot.
- vgatherps 5y agoThe claim that Go 'forces people to be pragmatic' applies a pretty strong value judgement to the way things Go does. You could say "Go forces people do things the way Go wants and this way is wonderful for many use cases" (I don't disagree), but whether that way is pragmatic or not depends on the use case.
- deleted 5y ago[deleted]
- vegai_ 5y agoDefinitely nothing bad can ever happen with complicated programming techniques. https://pbs.twimg.com/media/C6l_OwSXAAA_Fmo.jpg:large https://pbs.twimg.com/media/C6l_OwSXAAA_Fmo.jpg:large
- ogogmad 5y agoI think generics on their own are very simple, bordering on second nature. Their interaction with traits (or "interfaces" as some languages call them) can make them complicated. I guess Go needed to find a way to make that interaction work. By generics "on their own", I mean essentially the Hindley-Milner type system, which supports generics and can do static type inference in linear time: https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_sy... Somehow, the "generics wars" in Go made generics into the scapegoat of programming language complexity, when perhaps it was Go's "interfaces" feature all along. Maybe the enemy was here the whole time!
- liftm 5y agoIs there anything in Go that will help prevent those things that definitely can never happen?
- oblio 5y agoWishful thinking :-D
- deepsun 5y agoPeople used to blame Java for that.
- oblio 5y agoYeah, ramp it up to all the way to 11, C++. Or as they call it, "strawman". I don't think many people would call Java 1.5 or C# 2.0 super complicated. Do you know what Java 1.5 and C# 2.0 had in common, that Go didn't? Generics. For reference: - Java 1.5 - release date: September 30, 2004 - C# 2.0 - release date: January 22, 2006 That's ~18 years ago and 16 years ago, for whoever's keeping track.
- londons_explore 5y agoGenerics shouldn't make something faster... If they do, then there is a bug or missed optimization in the compiler.
- leeuw01 5y agoWhy?
- nokamok 5y agoThe way I understood it the “slowness” came from using interface{} in the queue implementation. With generics you get a performance boost from annihilating the run-time overhead. Yes?
- masklinn 5y ago> With generics you get a performance boost from annihilating the run-time overhead. Yes? I don't know whether creating an interface{} has a runtime cost (though it may if the type pointer has to be looked up at runtime?), however there's also a memory overhead: I didn't look at everything but the first two benches (pushfront and pushbach) use `int` values, which are 32 bits. But interface{} is 2 words (128 bits). This quadruples the memory requirements, meaning the backing buffer may well need either more reallocations, or to make larger allocations & have to span multiple cache lines.
- nokamok 5y agoI think you’re on to something. Just reread this article: https://blog.gopheracademy.com/advent-2018/interfaces-and-reflect/ https://blog.gopheracademy.com/advent-2018/interfaces-and-re... And there’s definitely an overhead associated with the interface type due to run-time reflection. I guess generics does away with this.
- ogogmad 5y ago~~If the type of something is "any", then that means your types are only truly known at runtime, and you therefore have to check the type of everything while the program is running. Am I off here? I don't use Go.~~ Maybe it's not so much runtime type checking, as the fact that a type of "any" means that the compiler doesn't know anything about what objects are in the deque. If you're using arrays to represent your deques, then this means you can't actually store the entries of the deque in the array, but only pointers to those entries, no? I think the keyword for what I'm saying is boxing/unboxing.
- londons_explore 5y agoAll those times in the table seem... Slow... For example, BenchmarkPushFront-10 takes 9 ns... That should consist of one write to memory (to update the pointer in the object). With decent compiler optimizations and a modern out of order CPU, I think we ought to be expecting one of those per clock cycle, so we ought to be seeing performance of 0.5ns. Perhaps even faster if the compiler manages to vectorize stuff (although I'm not aware of any compiler that can vectorize memory allocations).
- makapuf 5y agoWell we don't know what is being pushed or what was the function call overhead. Edit: the -10 suffix can mean there is a 10x loop in the benchmark?
- Svip 5y agoThe -10 indicates the number of CPUs used.[0] But the `ns/op` should per iteration of the benchmarking loop. [0] https://blog.logrocket.com/benchmarking-golang-improve-function-performance/ https://blog.logrocket.com/benchmarking-golang-improve-funct...
- innocenat 5y agoSkimming the code it looks like one operation is 10 push front, not just 1.
- foldr 5y agoSomething fishy here. A generic data structure is exactly the kind of code that you wouldn’t expect to perform better with generics. At most you’re getting the benefits of unboxing and the absence of a single conditional jump for the type check when you convert back from interface{}. But that shouldn’t make much difference to a series of tests that just push and pop items for a queue. I suspect that any realistic code using this data structure would see no tangible performance benefit. These tests are probably just picking up the cost of an extra allocation required to box a primitive type as an interface. If you’ll excuse the blog spam, I did a dive into the performance of interface{} here: https://adrummond.net/posts/gogenerics https://adrummond.net/posts/gogenerics (The blog post was written before it was certain that Go would get generics.)
- maxwell86 5y ago> At most you’re getting the benefits of unboxing Which is.. 3x? or 10x? > These tests are probably just picking up the cost of an extra allocation required to box a primitive type as an interface. I've seen unboxing deliver 100x speed ups cause it allowed the compiler to auto-vectorize multiple loops, fuse them, optimize stuff better etc. Stuff that it can't do if it doesn't know the memory layout of things, or if there are "optimization barriers" inserted in between all these steps (`interface {}`). --- TBH it's 2022 and it seems that "Go" devs are just seeing fire for the first time in their lives. Yeah, fire heats. And yeah, this type of stuff if why people don't put Go in the same bag of languages as C++ or Rust. Go feels fast if you are coming from Python, but if you actually look at what the hardware can deliver in terms of FLOPs and BW, Go programs run at 0% of hardware peak (and no, just because your task manager shows go threads using 100% of the CPU doesn't mean that it is achieving 100% of peak CPU perf).
- jpgvm 5y agoExactly. Go was (still is tbh) slow. that is why these improvements are possible. Fast is relative ofc but if you are going to introduce the words "low level" in your description then don't be surprised when C/C++/Rust rear their ugly (but very fast) heads.
- The_rationalist 5y ago
- native_samples 5y ago"This is encouraging news for a language already known to be unusually both fast and easy" Hmm it's not known for that, is it? Go is known to be quite slow due to a weak compiler and a GC that optimizes for latency over throughput. And is Go really easier than a language like Java or in the dynamic world, JavaScript? It sure does seem to have a lot of weird edge cases and potholes to trip over. Anyway I see a bunch of comments saying generics shouldn't make anything faster. They can make code go faster in combination with specialization and value types. It's one of the reasons C++ can go very fast whilst still supporting higher level abstractions, albeit at the cost of generated code size. It's also the reason they're adding value types and specialized generics to the JVM. I don't know if Go is doing C++/Rust style specialization or not, but it at least has the potential to do so.
- laumars 5y ago> Hmm it's not known for that, is it? It’s a hugely generalised statement so the real answer is “it really depends on your context” Is it fast compared to other easy to learn languages? Definitely. Is it fast compared to other systems languages? Lol no. But is it fast to compile compared to other systems languages? Generally, yeah. Is it easy to learn compared to other systems languages? Very much so. Is it easy to write complex low level systems logic? No. Is it easy to write dynamic code? No. The problem with generalised statements against general purpose languages is that the scope is so wide that people will cherry whatever context they want to suit whatever argument (for or against) they choose.
- threeseed 5y ago> Is it easy to learn compared to other systems languages? Very much so. I think this is debatable and depends on your background. If you come from a Java/C background then many things are unintuitive e.g. error handling, dynamic interfaces, package/library management, whitespace parsing, style enforcement etc. Golang is easy to learn right now because it's basic like say Java 1.2. But since it likes to ignore what other languages do I wouldn't say it's an inherently easy language.
- 5y ago
- dilap 5y agoNot really fair. You could already get this performance, when you cared, by writing the specialized datastructure for the specific types you cared about. So sure, generics let you write type-agnostic libraries that don't pay a boxing/unboxing penalty, but that's not really news!
- snovv_crash 5y agoI do a lot with specialized data structures for things like kNN or sparse adjacency matrices, in multiple different contexts. The fact that Go now has generics means I might actually consider it as a language, because I don't need to mess around with eg. codegen to have a maintainable base implementation.
- dilap 5y agoYeah no argument generics are very useful! But still, it's a bit of a clickbait headline -- Go isn't getting faster, it's just getting more ergonomic to write fast code. :-)
- xyzzy_plugh 5y agoMaybe I'm alone in this by, codegen is fine? After all, that's what generics is at some primitive level. The Go compiler is so bloody fast that recompiling is practically free. And it's very easy to write a code generator any number of ways.
- spoiler 5y agoBut isn't maintaining codegen more effort (and brittle) than just maintaining a generic implementation? Maye it's a matter of taste, though.
- snovv_crash 5y agoCodegen breaks debuggers.
- ogogmad 5y agokNN's and matrices? Go doesn't have operator overloading; are you sure you'd be happy using it for that?
- xyzzy_plugh 5y agoI don't believe Go is about to get faster, at least not in an especially unique way compared to past releases. Historically the Go compiler has been seeing performance improvements every release, so historically, Go has always been getting faster. When it comes to Generics, the benefits are not so straightforward as simply recompiling with a new binary. I just rebuilt one of our larger services with Go 1.17 and compared it to 1.18 and the benchmarks come out roughly the same after variance. There is a slight improvement, but what's interesting is that we don't use generics anywhere. My employer has a blanket ban on Generics in Go until at least the next release. I know others that do too. There is also nothing in our code base that is screaming to be rewritten with Generics. We collectively thought about it and no one could come up with anything worthwhile. Internally, we're still not sure when they're even warranted. Sure, there's a few three line for-loops that could be removed, but none of those are in a hot path. Yawn. If Go generics radically change the Go ecosystem overnight, they will ruin the language. The ecosystem prefers stability and compatibility over features, and it's pervasive and good. I update Java and JavaScript dependencies regularly and it's a fucking nightmare compared to Go. Lastly, Go had attracted a large community of developers who eschew unnecessary abstractions. It's lovely and refreshing. I can't say the same about Rust or Swift or Scala, where complexity is sometimes celebrated as simplicity when it's really just convenience wearing lipstick.
- SPBS 5y ago> eschew unnecessary abstractions The problem is, no one can agree on what is the 'necessary level of abstraction'. Where you stand on that scale determines whether you love or hate Go as a language.
- throw6622 5y agoIf I understand correctly, what you’re saying is “Go won’t immediately get faster with this release, it will immediately get faster with the next and subsequent releases”. Whether your employer uses generics or not, it’s very likely large parts of the standard library will get rewritten with them soon, and if OP is correct, it will improve the performance greatly of certain operations.
- 5y ago
- amelius 5y agoCompiler question: what is the most worthy replacement for the Dragon Book, these days?
- super_mario 5y agoEngineering a Compiler 2nd Edition by Keith D. Cooper and Linda Torczon is highly regarded.
- kinjba11 5y agoYou may also find https://craftinginterpreters.com/ https://craftinginterpreters.com/ useful.
- vvern 5y agoDeques are great. I think there's two ways I'd consider designing this library differently: 1) The resizing seems worse to me than a linked-list of fixed-size ring buffers which use a sync.Pool. 2) (more out there) some of the time when I've implemented this sort of thing, it's been to allocate memory for unmarshaling. It might be nice to have a mechanism to store values and allocate pointers.
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- upsidesinclude 5y agoGo Faster. Real missed opportunity here