Why does adding concurrency slow down this Go code?
The code provided simulates interactions with monsters in a game and the likelihood of item drops upon defeat. Despite expectations that the code should be perfectly suited for parallelization, adding concurrency significantly slowed it down.
Explanation:
The issue lies in the use of rand.Float64(), which relies on a shared global object with a mutex lock. When multiple goroutines attempt to use this function concurrently, they encounter contention for the lock, impeding performance.
Solution:
To resolve the issue, create a separate instance of the Rand struct for each goroutine and use that instance to generate random numbers. This eliminatec conttention for the global lock and allows for true parallelization.
Updated Code:
func interaction(generator *rand.Rand) int { if generator.Float64() <= DROP_RATE { return 1 } return 0 } func simulation(n int, generator *rand.Rand) []int { interactions := make([]int, n) for i := range interactions { interactions[i] = interaction(generator) } return interactions }
Improved Performance:
After applying the fixes to create new Rand instances for each goroutine, the resulting code shows a significant improvement in performance. The time taken to run the simulations is reduced by around 75% when using two processors.
Conclusion:
When using concurrency in Go, avoid relying on the shared global Rand instance. Instead, create separate instances of the Rand struct for each goroutine to ensure optimal performance.
The above is the detailed content of Why Does Concurrency Slow Down My Go Code Using `rand.Float64()`?. For more information, please follow other related articles on the PHP Chinese website!