4 ms·
> Ahem Maps are not concurrency-safe, you know what else isn't? Integers, floats, pointers, structs. And not only in Go, but in pretty much almost all language
by 4ad 11y ago
> Ahem
Maps are not concurrency-safe, you know what else isn't? Integers, floats, pointers, structs. And not only in Go, but in pretty much almost all languages with mutable state, like C and C++.
The map implementation in Go is consistent with the rest of the language, plus it allows for great performance under some rather common scenarios.
But I guess it's fashionable to snark on message boards than rather understand all these facts.
- grabcocque 11y agoI apologise for expecting better of language designers. After all, the solutions to these sorts of issues has only been around for a couple of decades. Far too soon.
- jrockway 11y agoAll the language designer can do is throw in a lock that you may or may not need if you're already locking properly. ConcurrentModificationException is nice, but comes at a performance cost.
- alkonaut 11y agoThis is a library thing, not a language thing. And it's a performance tradeoff: they could have shipped with a concurrent map only, that is 1/10 as fast as the current one, but never causes a data race. However everyone that isn't doing anything concurrently would be paying for it. Not very clever. I trust the class library designers thought this through. They reached the same conclusion as pretty much every other library designer in every other language. For the same reasons.
- netheril96 11y agoYou are not expecting better. You are expecting worse. Plenty of use cases involve maps without concurrent modification, e.g., when used as a local variable. Your "better" version of maps will slow down all of them.
- lazyjones 11y agoThe explanation for this design decision is reasonable IMHO: https://golang.org/doc/faq#atomic_maps https://golang.org/doc/faq#atomic_maps
- titzer 11y agoActually Java guarantees atomic accesses for integer-sized fields and references at the language level. They aren't race-free, but they are atomic. And really, atomicity is the main property that the OP had in mind when posting. Since you mentioned C++, it also does guarantee certain-sized certain-alignment loads and stores are atomic. In Java there is also the plethora of thread safe data structures available in java.util.concurrent. They are written by experts and are pretty darn fast (TM). It might have been reasonable to use one of these as the basis for Go map implementations, but the language designers chose to assume unsynchronized access to shared maps is a design bug in applications.
- jeremyjh 11y agoJava chooses safety over performance. It is not free to check for concurrent access in a non-concurrent structure. In some languages, we let the programmer take on the choice of which costs to bear. There is not very much that I like about Go, but there is nothing wrong with having non-concurrent data structures that are documented as such and fail in non-defined ways when there is shared data access.
- azth 11y ago> Java chooses safety over performance. Yet manages to be faster than golang. Also, the two need not be mutually exclusive as you're implying.
- viraptor 11y agoC got atomic values in C11: http://en.cppreference.com/w/c/language/atomic http://en.cppreference.com/w/c/language/atomic Not that I disagree with your comment in general, but atomic values do exist in many languages.
- AYBABTME 11y agoAlso in Go https://golang.org/pkg/sync/atomic/ https://golang.org/pkg/sync/atomic/
- 4ad 11y agoThanks for the reference, I knew about C11 atomic types, and, I should have use a better phrasing. Note that C11 atomics are still not applicable to multi-word aggregate types, like structs. You'd use atomics in C11 (in the type system), for what you'd use sync/atomic (like other poster mentioned) in Go (outside the type system).
- seanmcdirmid 11y ago32 bit data types are read and written atomically on the CLR. Pointers are read/written atomicly on most ANY platform, or you couldn't build any kind of higher level concurrency abstraction. If not, the language could never provide memory safety.
- 4ad 11y agoYou need a way to do atomic reads and writes, but you don't need to have atomic types. In Go you just use sync/atomic which implements atomicity outside the type system. When you use "regular" operations, you don't get atomicity, but what you get is well-defined, and explained here: https://golang.org/ref/mem https://golang.org/ref/mem.