LRU是Least Recently Used的缩写,即最近最少使用,常用于页面置换算法,是为虚拟页式存储管理服务的。
简单说就是缓存最近最常使用的服务或对象。
先来个很烂的草图(但能说明问题)
这个是整体的特效加载优化的流程图。主要就是对池子的操作,缓存起最近最常使用的特效。
using System;
using System.Collections.Generic;
using UnityEngine;
public class LRU<T> where T : UnityEngine.Object
{
private List<T> mDatas;
public delegate void OnAddData(T data);
public delegate void OnRemoveData(T data);
public OnAddData AddDataCallback;
public OnRemoveData RemoveDataCallback;
private uint mLimitNum = 30;
public uint LimitNum
{
get
{
return mLimitNum;
}
}
public List<T> MDatas
{
get
{
return mDatas;
}
}
public LRU(uint limitNum = 30)
{
mLimitNum = limitNum;
mDatas = new List<T>();
}
/// <summary>
/// 获取一个数据,注意,函数内不会新增数据,只能通过如果返回为null则AddData增加
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public T GetData(string data)
{
T rData = null;
for (int i = mDatas.Count - 1 ; i >= 0; i--)
{
//顺便把长度计算出来
var lData = mDatas[i];
if (lData == null)
{
continue;
}
if (data.CompareTo(lData.name) == 0)
{
rData = lData;
break;
}
}
return rData;
}
/// <summary>
/// 添加一个数据
/// </summary>
/// <param name="data"></param>
public void AddAndSortData(T data)
{
int dataIndex = mDatas.IndexOf(data);
if (dataIndex == -1)
{
mDatas.Insert(0, data);
if (data != null && AddDataCallback != null)
{
AddDataCallback(data);
}
}
else
{
mDatas.RemoveAt(dataIndex);
mDatas.Insert(0, data);
}
SortData();
}
/// <summary>
/// 重新排序或去除元素,使用对象得时候调用
/// </summary>
private void SortData()
{
if (mDatas.Count < mLimitNum)
{
return;
}
for (int i = mDatas.Count - 1; i >= 0; i--)
{
if (i >= mLimitNum)
{
if (mDatas[i] != null && RemoveDataCallback != null)
{
RemoveDataCallback(mDatas[i]);
}
mDatas.RemoveAt(i);
}
}
}
}
在用在特效的对象池身上,这样就可以更大概率的保证命中率了。特别是用在moba,rpg这些游戏。因为我们主角可能换的概率不大,那么缓存起来不销毁这些特效的话,那么下次进来就不需要再加载一遍。命中率比普通加载方式高很多。