22 ms·
Go 1.9 is released
- tmaly 9y agoI am looking forward to 1. runtime/pprof package now include symbol information 2. Concurrent Map 3. Profiler Labels 4. database/sql reuse of cached statements 5. The os package now uses the internal runtime poller for file I/O.
- Diederich 9y ago> 4. database/sql reuse of cached statements !! that wasn't a thing until now?
- bradfitz 9y agoIt was. That summary is a bit of a simplification. See https://golang.org/doc/go1.9#database/sql https://golang.org/doc/go1.9#database/sql Go 1.9 adds reuse of statement handles created off an ephemeral transaction too. But all the other statement handle cases have cached from day 1.
- tylersmith 9y agoYou could do it manually but it want automatic.
- alphaalpha101 9y agoSo this new concurrent map? Am I right in understanding it's designed for cases where you have a map shared between goroutines but where each goroutine essentially owns some subset of the keys in the map? So basically it's designed for cases like 'I have N goroutines and each one owns 1/N keys'?
- kraig 9y agoor you just have two or more goroutines that need to modify a map
- artursapek 9y agoIt could just be one map shared by many goroutines, which normally causes a panic: fatal error: concurrent map writes
- freecodyx 9y agoi am dealing with this problem right now. also i have a big problem with deepclone, I did a big rewrite of a current project, and clearly it was badly designed :(
- deleted 9y ago[deleted]
- azinman2 9y agoStandard practice is to use a mutex to guard against concurrent usage.
- logicallee 9y agoalso necessary for reads? Also, do you have any good references to proper best practices around concurrent and parallel programming? (in Go.) Like just basic things. Code I can copy and paste without it having obscure race conditions because that use of mutex is absolutely correct, and something that lets me understand the limitations. I feel like it is very easy to do things "wrong" or not notice some edge cases. In C++ I didn't only ever coded single-threaded for this reason. Too many gotchas. Any help would be appreciated.
- carbocation 9y agoNecessary for reads unless no additional writing will be done. If you initialize/write into a map and then later have concurrent reads from it, the program will run. If you try to write in the midst of this, it will crash.
- dgellow 9y agoI would suggest you to read the book "Concurrency in Go", by Katherine Cox-Budai, 2017: http://shop.oreilly.com/product/0636920046189.do http://shop.oreilly.com/product/0636920046189.do
- vanderZwan 9y ago> each goroutine essentially owns some subset of the keys in the map With those constraints, why not create a small map for each goroutine at that point, and merge the maps afterwards?
- imaginenore 9y agoThen you have to merge them on every read (after any modification).
- squiguy7 9y agoThis lightning talk gives some great information on use cases for the new sync.Map: https://youtu.be/C1EtfDnsdDs https://youtu.be/C1EtfDnsdDs
- deckarep 9y agoWow great find!
- alphaalpha101 9y agoI really, really don't understand why this would get downvoted. Are people not allowed to ask questions now?
- pvg 9y agoThey're discouraged from complaining about downvoting.
- alphaalpha101 9y agoIt was not a complaint, it was a question, just like my top-level comment. Was that interpreted as a complaint as well? Is that the problem?
- issaria 9y agoA concurrent map in my understanding, is a map that can be accessed concurrently without explicit synchronization, not each coroutine has a piece of it. Check java ConcurrentHashMap.
- pvg 9y agoIt sounded like complaining but either way, take a look at these. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html "Please don't comment about the voting on comments. It never does any good, and it makes boring reading."
- alpb 9y agot.Helper() is certainly going to be very useful. I often implement functions like: func testServer(t *testing.T, port int) { ...do stuff... if err != nil { t.Fatalf("failed to start server: %+v", err) } } similarly you can have func assertMapEquals(t *testing.T, a, b map[string]int) It lets you hide such helper methods from the test failure's stack trace (where t.Fatal is actually called), making test errors more readable.
- azinman2 9y agoYes indeed this is totally awesome. It’s a problem that occurs on any platform, and not only for testing. I often see this problem with logging as well, where some validation/helper function logs an error separate from the context it occurred in, potentially making it hard to trace without a stacktrace logged as well.
- throw4625 9y agoThis is the biggest problem with Go errors and one of my biggest gripes with the language. Exceptions have stacktraces that give you context about where the error originated. Go errors don't have this and it costs me a lot of time debugging things.https://godoc.org/github.com/pkg/errors https://godoc.org/github.com/pkg/errors helps, but it's still more of a pain than it should be.
- cpuguy83 9y agoErrors can be anything. It's just an interface.
- stouset 9y agoExcept you don't get to control the specific error type returned by packages you import. So sure, you could get stack traces for your code, but not for your dependencies. It infuriates me when go proponents try and sweep bad language decisions under the rug with half-fixes. https://twitter.com/codebeeCA/status/885302657178587136 https://twitter.com/codebeeCA/status/885302657178587136
- e12e 9y agoDoes anyone know of compile-time benchmarks spanning 1.4 through 1.9, along the lines of [1]? I see there's (more) parallel compilation in 1.9 - so that should improve elapsed time (but not reduce cpu time) of compilation. Would be nice to know if 1.9 is (still) on track catch up to/pass 1.4. [1] https://dave.cheney.net/2016/11/19/go-1-8-toolchain-improvements https://dave.cheney.net/2016/11/19/go-1-8-toolchain-improvem...
- kevinburke 9y agoDave posted one about halfway through the release cycle, showing a small improvement. That was before the parallel-function compilation though, so things might have gotten better since then.
- dilap 9y agoI was curious so I downloaded Go 1.4, and tested against 1.9 on an old version of a project I have (backend for Mafia Watch), about 30K lines of Go, including a few 3rd party dependencies. Go 1.4: Around 2.1s Go 1.9: Around 2.5s So within 20% of 1.4, not bad. That's on an old MacBook Air, dual core 1.7 GHz i7, 8GB ram. And of course the binary performance and GC pause times w/ 1.9 will be much better. Here's the raw times: https://pastebin.com/ULDHPmVu https://pastebin.com/ULDHPmVu Two awesome things: It was super-easy and fast to download and compile Go 1.4 It was completely painless to compile my old code with Go 1.9 I fucking love how nice it is to work with the Go ecosystem. <3
- cristaloleg 9y agoPlease remember that sync.Map isn't type safe and is more optimised for reads.
- kjksf 9y agointerface{} and therefore sync.Map is type safe. https://en.wikipedia.org/wiki/Type_safety https://en.wikipedia.org/wiki/Type_safety > Type enforcement can be static, catching potential errors at compile time, or dynamic, associating type information with values at run-time and consulting them as needed to detect imminent errors, or a combination of both. interface{} is type-checked at runtime. It's type-safe because because you can't e.g. fish out an integer out of interface{} value that represents a string. Runtime won't allow it. You can either extract a string or the runtime will crash if you insist on extracting anything else. Unless you use unsafe package, in which case you explicitly want to skip type-safety.
- ryeguy 9y agoWhen "type safe" is mentioned without qualification, it almost always refers to static type safety. This is one of those times. So no, the sync.Map container is not typesafe like a regular map is.
- kjksf 9y agoAccording to whom? Certainly not according to wikipedia. Given that it's a pretty big distinction I would think it's on the speaker to be un-ambiguous and say "it's not statically type safe" vs. ambiguous "type safe". I've certainly seen my share of people claiming that "interface{} is just like void * in C" when they speak about Go's (lack of) type safety. I also don't see how insisting on accurate and un-ambiguous terminology ticks people off so much to downvote. I imagine they think I said something much more incorrect than I did.
- andrewjw 9y ago"type safe" has come to mean "statically type safe" over time in common conversation. You were downvoted because this intended usage was clear to the people who downvoted you and their perception of your comment was that it provided no value, e.g. was a nitpick. I would note that the Wikipedia page does not take as strong a position as you seem to imply, reading: > In the context of static (compile-time) type systems, type safety usually involves (among other things) a guarantee that the eventual value of any expression will be a legitimate member of that expression's static type. The precise requirement is more subtle than this — see, for example, subtype and polymorphism for complications. Since golang is statically typed, type safety is generally understood to mean static type safety.
- tschellenbach 9y agoNice can't wait to run some of our benchmarks against this. Go has the awesome property of always becoming a little bit faster every release. It's like your code becomes better without doing anything. Love it :)
- rjammala 9y agoThis is what they mentioned in 2015. See slide 3 in this pdf: https://talks.golang.org/2015/go-gc.pdf https://talks.golang.org/2015/go-gc.pdf
- ivan4th 9y agoI was looking forward to the fix for the dreaded Linux namespace handling problem: https://www.weave.works/blog/linux-namespaces-and-go-don-t-mix https://www.weave.works/blog/linux-namespaces-and-go-don-t-m... which kind of makes Go suck for many important container-related tasks. But apparently the effort has stalled... https://go-review.googlesource.com/c/go/+/46033 https://go-review.googlesource.com/c/go/+/46033
- bradfitz 9y agoIt doesn't look stalled. It looks targeted towards Go 1.10, not Go 1.9.
- deleted 9y ago[deleted]
- valarauca1 9y agoThere really aren't great solutions to this in C/C++ having one application share state/memory across namespaces/users is a v hard problem
- dullgiulio 9y agoThis has been discussed and the discussion derailed very quickly ("Go is a joke, my language has it bigger, blah blah".) Reality is that the Linux Kernel makes a big confusion between processes and threads in the userspace APIs. Locking to threads is a solution that works but also sucks and defeats the niceties of Go N:M model. But that's the only way: if you use that broken system calls API you should know better.
- old-gregg 9y agoIn case someone cares about these things, I compared the build times and the binary sizes for 1.9 vs 1.8.3 using the open source project we maintain [1]. This is on a 6-core i7-5280K: Build time with 1.8.3: real 0m7.533s user 0m36.913s sys 0m2.856s Build time with 1.9: real 0m6.830s user 0m35.082s sys 0m2.384s Binary size: 1.8.3 : 19929736 bytes 1.9 : 20004424 bytes So... looks like the multi-threaded compilation indeed delivers better build times, but the binary size has increased slightly. [1] You can git-clone and try yourself: https://github.com/gravitational/teleport https://github.com/gravitational/teleport
- amenghra 9y agoUnless you perform a proper statistical analysis it's unfair to draw a conclusion from a single run. Furthermore, when I see a second run that's faster than the first one, I immediately wonder if it's the cache being cold for the first run and warm for the second. While I have your attention, https://zedshaw.com/archive/programmers-need-to-learn-statistics-or-i-will-kill-them-all/ https://zedshaw.com/archive/programmers-need-to-learn-statis... is worth reading.
- ovao 9y agoIn fairness, the phrase he used was "looks like". I don't think his comment was intended to suggest that he'd done rigorous and exhaustive wide-spectrum analysis of compile times and executable size, just that expectations matched the result for his project.
- old-gregg 9y agoThanks :) I'm no stranger to the scrutiny of Hacker News, I did 3 builds in a row and threw out the 1st one (cache), the last two were within 0.1s of each other, so I copied & pasted the latter.
- fredmorcos 9y agoSo basically there's no speedup.
- kokwak 9y agoPlease add enum class
- Scorpiion 9y agoIn the release notes it says: "Mutex is now more fair." Source: https://golang.org/doc/go1.9#sync https://golang.org/doc/go1.9#sync Does anyone know what that means?
- fmela 9y agoThis is the relevant change: https://github.com/golang/go/commit/0556e26273f704db73df9e7c4c3d2e8434dec7be https://github.com/golang/go/commit/0556e26273f704db73df9e7c...
- Scorpiion 9y agoThanks for the link! =)
- emfree 9y agoYou piqued my curiosity :) A comment in the source for the release notes (https://github.com/golang/go/blob/master/doc/go1.9.html#L922 https://github.com/golang/go/blob/master/doc/go1.9.html#L922) points to the relevant change: https://go-review.googlesource.com/c/go/+/34310 https://go-review.googlesource.com/c/go/+/34310, which in turn links to this issue: https://github.com/golang/go/issues/13086 https://github.com/golang/go/issues/13086
- Scorpiion 9y agoAh, thanks for the links. I googled a little bit and found some good info, I guess I had forgotten a little bit of the concepts of mutex fairness/unfairness. I found a very nice explanation on cs.stackexchange: "My understanding is that most popular implementations of a mutex (e.g. std::mutex in C++) do not guarantee fairness -- that is, they do not guarantee that in instances of contention, the lock will be acquired by threads in the order that they called lock(). In fact, it is even possible (although hopefully uncommon) that in cases of high contention, some of the threads waiting to acquire the mutex might never acquire it." Source: https://cs.stackexchange.com/questions/70125/why-are-most-mutex-implementations-unfair https://cs.stackexchange.com/questions/70125/why-are-most-mu... With that computer science clarification, I think the comment "Mutex is now more fair" and the detailed description "Unfair wait time is now limited to 1ms" makes it a lot clearer. Great improvement I think! It's one of those things that you don't notice until you have a bug, but it's really nice to never get that bug in the first place. =)
- zkanda 9y agoIn case you guys didn't know, there's multiple release party in different parts of the world: https://github.com/golang/cowg/blob/master/events/2017-08-go1.9-release-party.md https://github.com/golang/cowg/blob/master/events/2017-08-go... Come join if your near the area.
- baby 9y agoNone in London :(
- riobard 9y agoI'm wondering if we could abuse type alias to fake generics somehow? E.g. // file tree.go type T = YourConcreteType type TreeNode struct { Value T } // rest of tree implementation Then you can just copy the file and replace YourConcreteType at the top and voila! Seems simpler to use than the unicode hack here https://www.reddit.com/r/rust/comments/5penft/parallelizing_enjarify_in_go_and_rust/dcsgk7n/ https://www.reddit.com/r/rust/comments/5penft/parallelizing_...
- ptman 9y agoWhat if I want both TreeNode<float64> and TreeNode<rune>?
- stewbrew 9y agoNow make that a compile time thing that happens on imports and that doesn't generate temporary source files and whoop you have modules with generics. Oops, I forgot that there are some unsolvable obstacles to be resolved.
- jhgb 9y agoI have been wondering for quite some time how one could implement that. That is, not in the sense of how to code that, but rather how few changes one would have to make to the language to get as many effects as possible in the direction of genericity. There is some inspiration in Lua, Scheme48 and some dialects of ML (functors, I believe?) in the form of "higher-order modules", where the module (would be package in Go?) could have parameters that you'd have to supply when importing it. The things you could obviously supply would be at least constants, functions and types. (One might look at functions as types of computational processes, though, and at function signatures/interfaces as their respective type classes. This perspective could subsume functions as types, and perhaps integers as nullary functions returning an integer.) The question is how to reasonably do the import strings. Good thing about Go is that you already have provisions in the language in the sense that the string can be technically arbitrary. A subset of the reflection interface could additionally be evaluated at compile time to provide for ad-hoc specializations of generic code by writing straightforward code that would be easily eliminated/specialized in a module instantiation (like loops over struct fields etc.)