関数キャッシュは、関数呼び出しの結果を再利用のために保存し、計算の繰り返しを回避するパフォーマンス最適化テクノロジです。 Go では、map または sync.Map を使用して関数キャッシュを実装でき、特定のシナリオに応じてさまざまなキャッシュ戦略を採用できます。たとえば、単純なキャッシュ戦略ではすべての関数パラメーターをキャッシュ キーとして使用しますが、洗練されたキャッシュ戦略ではスペースを節約するために結果の一部のみをキャッシュします。さらに、安全なキャッシュと無効化戦略を同時に実行することで、キャッシュのパフォーマンスをさらに最適化できます。これらの手法を適用することで、関数呼び出しの実行効率を大幅に向上させることができます。
関数キャッシュは一般的なパフォーマンス最適化テクノロジであり、将来の再利用に備えて関数呼び出しの結果を保存できます。 。これにより、関数が呼び出されるたびに同じ計算を実行する必要がなくなり、パフォーマンスが向上します。
単純なキャッシュ戦略:関数のすべてのパラメーターをキャッシュ キーとして使用し、関数の結果をマップに直接キャッシュします。
func computeCircleArea(radius float64) float64 { return math.Pi * radius * radius } var areaCache = make(map[float64]float64) func CachedComputeCircleArea(radius float64) float64 { if area, ok := areaCache[radius]; ok { return area } result := computeCircleArea(radius) areaCache[radius] = result return result }
洗練されたキャッシュ戦略:スペースを節約するために、関数パラメーターに基づいて結果の一部のみをキャッシュできます。たとえば、円の面積を計算する関数の場合、半径が 0 から 1 までの結果のみをキャッシュできます。
func computeCircleArea(radius float64) float64 { return math.Pi * radius * radius } var areaCache = make(map[float64]float64) func CachedComputeCircleArea(radius float64) float64 { if 0 <= radius && radius <= 1 { if area, ok := areaCache[radius]; ok { return area } result := computeCircleArea(radius) areaCache[radius] = result return result } return computeCircleArea(radius) }
同時実行安全キャッシュ:同時実行環境では、同時実行安全データ構造を使用して関数キャッシュを実装する必要があります。たとえば、sync.Map
:
package main import ( "math" "sync" ) func computeCircleArea(radius float64) float64 { return math.Pi * radius * radius } var areaCache sync.Map func CachedComputeCircleArea(radius float64) float64 { if area, ok := areaCache.Load(radius); ok { return area.(float64) } result := computeCircleArea(radius) areaCache.Store(radius, result) return result }
無効化ポリシー:を使用できます。場合によっては、キャッシュ内の結果が無効になることがあります。たとえば、円の面積を計算する関数の実装が変更されると、キャッシュされた結果は無効になります。この状況は、有効期限を設定するか、関数の結果が変化したときにキャッシュをクリアすることで対処できます。
関数slowOperation()
があるとします。その計算には非常に時間がかかります。関数キャッシュを使用して最適化できます:
package main import ( "sync/atomic" "time" ) var operationCount int64 func slowOperation() float64 { count := atomic.AddInt64(&operationCount, 1) print("执行 slowOperation ", count, " 次\n") time.Sleep(100 * time.Millisecond) return 1.0 } var operationCache sync.Map func CachedSlowOperation() float64 { // 将函数参数 nil(空指针)作为缓存键 if result, ok := operationCache.Load(nil); ok { return result.(float64) } result := slowOperation() operationCache.Store(nil, result) return result } func main() { for i := 0; i < 10; i++ { t := time.Now().UnixNano() _ = CachedSlowOperation() print("优化后花费 ", (time.Now().UnixNano() - t), " ns\n") t = time.Now().UnixNano() _ = slowOperation() print("原始花费 ", (time.Now().UnixNano() - t), " ns\n") } }
出力結果:
执行 slowOperation 1 次 优化后花费 0 ns 执行 slowOperation 2 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 3 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 4 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 5 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 6 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 7 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 8 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 9 次 原始花费 100000000 ns 优化后花费 0 ns 执行 slowOperation 10 次 原始花费 100000000 ns 优化后花费 0 ns
出力結果からわかるように、関数キャッシュを使用すると、遅い操作の実行時間が大幅に短縮されます。
以上がGolang 関数のキャッシュ パフォーマンス最適化のヒントの共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。