Announcement

👇Official Account👇

图片

Welcome to join the group & private message

Article first/tail QR code

Skip to content

提升 Wails 应用性能:探索 Go-Cache 的高效内存缓存方案

在 Wails 桌面应用中合理使用缓存,能显著提升应用性能和响应速度。

一、为什么需要缓存

1.1 桌面应用的性能挑战

  • 频繁的数据查询:重复读取相同数据
  • 计算密集型操作:重复计算相同结果
  • UI 响应延迟:等待数据加载

1.2 缓存的收益

场景无缓存有缓存提升
配置读取10ms0.1ms100x
数据查询100ms1ms100x
复杂计算1000ms10ms100x

二、Go-Cache 简介

2.1 特点

  • 线程安全
  • 支持过期时间
  • 支持自动清理
  • 高性能

2.2 安装

bash
go get github.com/patrickmn/go-cache

三、基础使用

3.1 创建缓存

go
package cache

import (
    "time"
    "github.com/patrickmn/go-cache"
)

var (
    // 默认缓存实例
    defaultCache *cache.Cache
)

func Init() {
    // 创建缓存,默认过期时间 5 分钟,每 10 分钟清理一次
    defaultCache = cache.New(5*time.Minute, 10*time.Minute)
}

func GetDefault() *cache.Cache {
    return defaultCache
}

3.2 基本操作

go
// 设置缓存
defaultCache.Set("key", "value", cache.DefaultExpiration)

// 设置永不过期
defaultCache.Set("key", "value", cache.NoExpiration)

// 获取缓存
value, found := defaultCache.Get("key")
if found {
    // 使用 value
}

// 删除缓存
defaultCache.Delete("key")

// 检查存在
_, found := defaultCache.Get("key")

四、Wails 集成

4.1 应用缓存服务

go
package backend

import (
    "encoding/json"
    "time"
    "github.com/patrickmn/go-cache"
)

type CacheService struct {
    cache *cache.Cache
}

func NewCacheService() *CacheService {
    return &CacheService{
        cache: cache.New(10*time.Minute, 30*time.Minute),
    }
}

// Get 获取缓存
func (cs *CacheService) Get(key string) (interface{}, bool) {
    return cs.cache.Get(key)
}

// Set 设置缓存
func (cs *CacheService) Set(key string, value interface{}, durationSeconds int) {
    duration := time.Duration(durationSeconds) * time.Second
    cs.cache.Set(key, value, duration)
}

// Delete 删除缓存
func (cs *CacheService) Delete(key string) {
    cs.cache.Delete(key)
}

// Clear 清空缓存
func (cs *CacheService) Clear() {
    cs.cache.Flush()
}

4.2 数据服务集成

go
type DataService struct {
    cache *CacheService
    db    *Database
}

func (ds *DataService) GetUser(userID string) (*User, error) {
    // 先查缓存
    cacheKey := "user:" + userID
    if cached, found := ds.cache.Get(cacheKey); found {
        return cached.(*User), nil
    }
    
    // 缓存未命中,查数据库
    user, err := ds.db.GetUser(userID)
    if err != nil {
        return nil, err
    }
    
    // 写入缓存
    ds.cache.Set(cacheKey, user, 300) // 缓存 5 分钟
    
    return user, nil
}

func (ds *DataService) UpdateUser(user *User) error {
    // 更新数据库
    if err := ds.db.UpdateUser(user); err != nil {
        return err
    }
    
    // 更新缓存
    cacheKey := "user:" + user.ID
    ds.cache.Set(cacheKey, user, 300)
    
    return nil
}

五、高级用法

5.1 缓存装饰器

go
// Cacheable 缓存装饰器
func Cacheable(cache *cache.Cache, key string, ttl time.Duration, fn func() (interface{}, error)) (interface{}, error) {
    // 检查缓存
    if value, found := cache.Get(key); found {
        return value, nil
    }
    
    // 执行函数
    result, err := fn()
    if err != nil {
        return nil, err
    }
    
    // 写入缓存
    cache.Set(key, result, ttl)
    
    return result, nil
}

// 使用示例
func (s *Service) GetConfig() (*Config, error) {
    result, err := Cacheable(s.cache, "config", 1*time.Hour, func() (interface{}, error) {
        return s.loadConfigFromDB()
    })
    
    if err != nil {
        return nil, err
    }
    
    return result.(*Config), nil
}

5.2 缓存预热

go
func (s *Service) WarmUpCache() error {
    // 加载常用数据到缓存
    users, err := s.db.GetAllUsers()
    if err != nil {
        return err
    }
    
    for _, user := range users {
        key := "user:" + user.ID
        s.cache.Set(key, user, 10*time.Minute)
    }
    
    return nil
}

六、总结

策略适用场景
读取缓存频繁读取的数据
写入更新数据变更时更新缓存
装饰器模式通用缓存逻辑
缓存预热应用启动时

合理使用缓存能让 Wails 应用响应更快,用户体验更好。

上次更新于: