Browse Source

Avoid allocating too many CostInterval objects

pull/1846/head
Brian Popow 5 years ago
parent
commit
7c1f05b0a8
  1. 37
      src/ImageSharp/Formats/Webp/Lossless/CostManager.cs

37
src/ImageSharp/Formats/Webp/Lossless/CostManager.cs

@ -14,6 +14,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
{
private CostInterval head;
private const int FreeIntervalsStartCount = 25;
private readonly Stack<CostInterval> freeIntervals = new(FreeIntervalsStartCount);
public CostManager(ushort[] distArray, int pixCount, CostModel costModel)
{
int costCacheSize = pixCount > BackwardReferenceEncoder.MaxLength ? BackwardReferenceEncoder.MaxLength : pixCount;
@ -24,6 +28,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
this.DistArray = distArray;
this.Count = 0;
for (int i = 0; i < FreeIntervalsStartCount; i++)
{
this.freeIntervals.Push(new CostInterval());
}
// Fill in the cost cache.
this.CacheIntervalsSize++;
this.CostCache.Add(costModel.GetLengthCost(0));
@ -201,10 +210,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
this.InsertInterval(interval, interval.Cost, interval.Index, end, endOriginal);
break;
}
else
{
interval.End = start;
}
interval.End = start;
}
}
@ -226,6 +233,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
this.ConnectIntervals(interval.Previous, interval.Next);
this.Count--;
interval.Next = null;
interval.Previous = null;
this.freeIntervals.Push(interval);
}
private void InsertInterval(CostInterval intervalIn, float cost, int position, int start, int end)
@ -236,13 +247,19 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
// TODO: should we use COST_CACHE_INTERVAL_SIZE_MAX?
var intervalNew = new CostInterval()
CostInterval intervalNew;
if (this.freeIntervals.Count > 0)
{
Cost = cost,
Start = start,
End = end,
Index = position
};
intervalNew = this.freeIntervals.Pop();
intervalNew.Cost = cost;
intervalNew.Start = start;
intervalNew.End = end;
intervalNew.Index = position;
}
else
{
intervalNew = new CostInterval() { Cost = cost, Start = start, End = end, Index = position };
}
this.PositionOrphanInterval(intervalNew, intervalIn);
this.Count++;

Loading…
Cancel
Save