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

Loading…
Cancel
Save