第一章:并发与泛型基础
2. 并发应用性能基准测试
使用并发生成素数
生成素数是一种经典的计算密集型任务,可以通过并发来提高效率。以下示例展示了如何使用 Go 并发生成素数。
埃拉托色尼筛法
埃拉托色尼筛法是一种简单且有效的素数生成算法。其基本思想是从小到大枚举每个数,标记出所有该数的倍数为非素数。
func sieve(n int) []bool {
primes := make([]bool, n+1)
for i := 2; i <= n; i++ {
primes[i] = true
}
for p := 2; p*p <= n; p++ {
if primes[p] {
for i := p * p; i <= n; i += p {
primes[i] = false
}
}
}
return primes
}
这段代码展示了基本的埃拉托色尼筛法。
分段筛算法
分段筛算法是一种改进的素数生成算法,通过将大范围的素数生成分成若干小段来减少内存使用,并利用并发来提高性能。
func segmentedSieve(n int) []int {
limit := int(math.Sqrt(float64(n))) + 1
primes := sieve(limit)
low := limit
high := 2 * limit
for low < n {
if high >= n {
high = n
}
mark := make([]bool, limit+1)
for i := 2; i < limit; i++ {
if primes[i] {
loLim := int(math.Floor(float64(low/i)) * float64(i))
if loLim < low {
loLim += i
}
for j := loLim; j < high; j += i {
mark[j-low] = true
}
}
}
for i := low; i < high; i++ {
if !mark[i-low] {
fmt.Println(i)
}
}
low = low + limit
high = high + limit
}
}
这段代码展示了分段筛算法的实现。
并发筛法解决方案
通过利用 Goroutine 和 Channel,可以并发地执行筛法算法,从而提高性能。
func concurrentSieve(n int, primes chan int) {
sieve := make([]bool, n+1)
for i := 2; i <= n; i++ {
sieve[i] = true
}
for p := 2; p*p <= n; p++ {
if sieve[p] {
for i := p * p; i <= n; i += p {
sieve[i] = false
}
}
}
for p := 2; p <= n; p++ {
if sieve[p] {
primes <- p
}
}
close(primes)
}
func main() {
n := 100
primes := make(chan int, n)
go concurrentSieve(n, primes)
for p := range primes {
fmt.Println(p)
}
}
这段代码展示了如何使用 Goroutine 并发地执行埃拉托色尼筛法。
通过这些示例,读者可以学习如何在 Go 语言中使用并发技术来优化计算密集型任务,并对其性能进行基准测试。