StringBuilder、MemoryStream等的自增长容器自增长原理是在需要是重新分配更大内部数组或其它。而重新分配就意味着原空间的垃圾生成加重垃圾回收的负担,在内存资源紧张的情况中可能会有比较大的问题产生。因此写了这个自适应库,实践中效果良好。值得注意到是本库适用于访问量比较大的场合。如果访问不很频繁,不需要使用词库,垃圾回收可以很好的处理这些垃圾。
基本原理:
采集一定数量样本sampleCount,设定调整因子levelFactor=80%,然后分析样本,效率原因,这里简单的提取可以适应levelFactor(这里没有取100%是为了剔除少数异常情况,当然各位可以修改为100%)样本大小的数值作为优化值,取优化值的levelFactor(80%)值作为降级线。当失败数量大于levelFactor或降级数大于levelFactor时重新设定优化值。
1、样本数据结构
class FitSizeTrackItem
{
public int size;
public DateTime enterTime;
}
2、序列优化类
class FitSizeTrackSeries : IComparer<FitSizeTrackItem>
{
private int ttlMinutes = 60 * 24 * 3;
private int optimized;
private int floatDownAlertValue;
private int sampleCount;
private int biggerCount;
private int smallerCount;
private bool optiRunning = false;
private double downGradeFactor;
private double levelFactor;
private FloatChannel<FitSizeTrackItem> channel;
public FitSizeTrackSeries()
{
InitSeries(0.8, 0.5, 100);
}
public FitSizeTrackSeries(double lvlFactor, double downFactor, int sample)
{
InitSeries(lvlFactor, downFactor, sample);
}
void InitSeries(double lvlFactor, double downFactor, int sample)
{
levelFactor = lvlFactor;
sampleCount = sample;
downGradeFactor = downFactor;
channel = new FloatChannel<FitSizeTrackItem>(sampleCount);
}
public void Track(int size)
{
FitSizeTrackItem item = new FitSizeTrackItem();
item.enterTime = DateTime.Now;
item.size = size;
channel.Put(item);
if (item.size > optimized) ++biggerCount;
else if (item.size < floatDownAlertValue) ++smallerCount;
if (biggerCount % sampleCount > levelFactor * 100 || smallerCount % sampleCount > downGradeFactor * 100)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Optimize));
}
}
public int Optimized
{
get { return optimized; }
set { floatDownAlertValue = optimized = value; }
}
void Optimize(object state)
{
if (optiRunning) return;
optiRunning = true;
try
{
biggerCount = (int)(sampleCount * (1 - levelFactor));
List<FitSizeTrackItem> list = new List<FitSizeTrackItem>();
for (int i = 0; i < channel.Length; ++i)
{
if (IsValid(channel[i]))
{
list.Add(channel[i]);
}
}
list.Sort(this);
optimized = list[(int)(levelFactor * (list.Count - 1))].size;
floatDownAlertValue = (int)(list[0].size + levelFactor * (optimized - list[0].size));
smallerCount = 0;
for (int i = list.Count - 1; i >= 0; --i)
if (list[i].size < floatDownAlertValue)
++smallerCount;
}
finally
{
optiRunning = false;
}
}
bool IsValid(FitSizeTrackItem item)
{
return item != null && DateTime.Now.Subtract(item.enterTime).TotalMinutes < ttlMinutes;
}
public int Compare(FitSizeTrackItem item1, FitSizeTrackItem item2)
{
return item1.size - item2.size;
}
}
5、使用方法:
}
}
}