Concurrency Slows Down Golang Code
In a bid to optimize code simulating interactions with monsters and item drops, concurrency was introduced, surprisingly affecting performance negatively.
The original code, without concurrency, had three main functions: interaction, simulation, and test. interaction simulated a single interaction and returned a 1 for item drop or 0 otherwise. simulation executed multiple interactions and stored the results in a slice. test ran a series of simulations and stored the total number of successful interactions in a slice.
When concurrency was added, goroutines were created for each test, with each goroutine running with its own copy of simulation. However, performance worsened instead of improving.
Reason for Slowdown
The issue lay in the rand.Float64() function, which uses a shared global object with a Mutex lock. By default, each goroutine would acquire this Mutex lock when calling rand.Float64(), ultimately slowing down performance.
Solution
To fix this, a separate rand.New() instance was created for each CPU. This eliminated the shared Mutex lock problem and significantly improved performance.
Additional Improvement
A further performance gain was achieved by replacing the rand.Float64() convenience function with direct calls to the Rand struct. The convenience function uses a global mutex-protected Rand instance, while the direct calls avoid this overhead.
Conclusion
While concurrency can enhance performance for certain problems, proper implementation is crucial. In this case, using separate rand.New() instances and avoiding shared Mutex locks were key to minimizing performance degradation.
The above is the detailed content of Why Did Adding Concurrency Slow Down My Go Code?. For more information, please follow other related articles on the PHP Chinese website!