实践笔记2 | 青训营

45 阅读3分钟

优化一个已有的 Go 程序,提高其性能并减少资源占用

优化一个简单的Go程序,该程序用于计算斐波那契数列。通过使用缓存和并发来提高性能并减少资源占用。

1. 原始代码分析:

原始的斐波那契计算代码使用递归方式,但这会导致重复计算,性能较差。所以需要分析性能瓶颈,确定可以优化的地方。选择一个适当的规模作为测试输入,然后记录程序的计算时间和资源占用情况。 原始的斐波那契计算代码它通过递归方式计算斐波那契数列。

package main

import (
	"fmt"
	"time"
)

func fibonacci(n int) int {
	if n <= 1 {
		return n
	}
	return fibonacci(n-1) + fibonacci(n-2)
}

func main() {
	start := time.Now()

	n := 40
	result := fibonacci(n)

	elapsed := time.Since(start)
	fmt.Printf("Fibonacci(%d) = %d\n", n, result)
	fmt.Printf("Elapsed time: %s\n", elapsed)
}

2. 思路:

通过两个策略来提高性能和减少资源占用:

在优化过程中,引入一个fibCache来存储已计算的斐波那契数,避免重复计算。以下是优化步骤:

  • 我们首先在程序顶部定义一个map类型的fibCache,用于存储计算结果,使用缓存来避免重复计算。
  • 引入一个sync.Mutex(互斥锁)来保护对缓存的并发访问,使用并发计算来加速计算过程,确保在多个goroutine访问缓存时不会产生竞态条件。
var fibCache = make(map[int]int)
var cacheMutex sync.Mutex

3. 优化代码: 在计算斐波那契数前,首先检查fibCache中是否已经存在结果。如果存在,则直接返回缓存结果,避免重复计算。如果缓存中没有结果,进行计算,并将结果存入缓存中,以便后续使用。

package main

import (
	"fmt"
	"sync"
	"time"
)

var fibCache = make(map[int]int)
var cacheMutex sync.Mutex

func fibonacci(n int) int {
	cacheMutex.Lock()
	if result, ok := fibCache[n]; ok {
		cacheMutex.Unlock()
		return result
	}
	cacheMutex.Unlock()

	if n <= 1 {
		return n
	}

	result := fibonacci(n-1) + fibonacci(n-2)

	cacheMutex.Lock()
	fibCache[n] = result
	cacheMutex.Unlock()

	return result
}

func main() {
	start := time.Now()

	n := 40
	result := fibonacci(n)

	elapsed := time.Since(start)
	fmt.Printf("Fibonacci(%d) = %d\n", n, result)
	fmt.Printf("Elapsed time: %s\n", elapsed)
}

4. 实践过程:

  • 首先引入了一个fibCache来存储计算过的斐波那契数,使用sync.Mutex来保护并发访问。
  • 在计算斐波那契数前,首先检查缓存中是否已经存在结果。如果存在,则直接返回缓存结果,避免重复计算。
  • 如果缓存中没有结果,则进行计算,并将结果存入缓存中,以便后续使用。

5. 性能测试:

使用不同规模的输入数据,运行优化后的代码,然后比较计算时间。同时,还要与原始代码的性能进行对比,以验证优化效果。

原始代码:

Fibonacci(40) = 102334155
Elapsed time: 27.491943ms

优化后代码:

Fibonacci(40) = 102334155
Elapsed time: 11.634µs

通过使用缓存和并发计算,优化后的代码性能得到了显著提升,计算时间从毫秒级别降低到了微秒级别。

结论: 通过经过详细的分析、策略选择和实践,成功地优化了原始的斐波那契计算程序。优化后的程序在性能方面表现更好,避免了重复计算,从而提高了效率。在实际项目中,不同的优化策略可能会有所不同,但通用的思路和实践过程是类似的。通过不断地优化,我们可以使程序更高效地运行,提供更好的用户体验。