diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index bd6c11235..2fe3c26e2 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp /// /// Gets or sets the that is currently in use. /// - public MemoryManager MemoryManager { get; set; } = new ArrayPoolMemoryManager(); + public MemoryManager MemoryManager { get; set; } = ArrayPoolMemoryManager.CreateWithNormalPooling(); /// /// Gets the maximum header size of all the formats. diff --git a/src/ImageSharp/Memory/ArrayPoolMemoryManager.CommonFactoryMethods.cs b/src/ImageSharp/Memory/ArrayPoolMemoryManager.CommonFactoryMethods.cs new file mode 100644 index 000000000..918c5d41a --- /dev/null +++ b/src/ImageSharp/Memory/ArrayPoolMemoryManager.CommonFactoryMethods.cs @@ -0,0 +1,46 @@ +namespace SixLabors.ImageSharp.Memory +{ + /// + /// Contains common factory methods and configuration constants. + /// + public partial class ArrayPoolMemoryManager + { + /// + /// The default value for: maximum size of pooled arrays in bytes. + /// Currently set to 32MB, which is equivalent to 8 megapixels of raw data. + /// + internal const int DefaultMaxPooledBufferSizeInBytes = 32 * 1024 * 1024; + + /// + /// The value for: The threshold to pool arrays in which has less buckets for memory safety. + /// + private const int DefaultBufferSelectorThresholdInBytes = 8 * 1024 * 1024; + + /// + /// This is the default. Should be good for most use cases. + /// + /// The memory manager + public static ArrayPoolMemoryManager CreateWithNormalPooling() + { + return new ArrayPoolMemoryManager(DefaultMaxPooledBufferSizeInBytes, DefaultBufferSelectorThresholdInBytes, 8, 24); + } + + /// + /// For environments with limited memory capabilities. Only small images are pooled, which can result in reduced througput. + /// + /// The memory manager + public static ArrayPoolMemoryManager CreateWithModeratePooling() + { + return new ArrayPoolMemoryManager(1024 * 1024, 1024 * 16, 16, 24); + } + + /// + /// RAM is not an issue for me, gimme maximum througput! + /// + /// The memory manager + public static ArrayPoolMemoryManager CreateWithAggressivePooling() + { + return new ArrayPoolMemoryManager(128 * 1024 * 1024, 32 * 1024 * 1024, 16, 32); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs b/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs index 7c2240a57..36bc3a870 100644 --- a/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs +++ b/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs @@ -11,17 +11,6 @@ namespace SixLabors.ImageSharp.Memory /// public partial class ArrayPoolMemoryManager : MemoryManager { - /// - /// The default value for: maximum size of pooled arrays in bytes. - /// Currently set to 32MB, which is equivalent to 8 megapixels of raw data. - /// - internal const int DefaultMaxPooledBufferSizeInBytes = 32 * 1024 * 1024; - - /// - /// The value for: The threshold to pool arrays in which has less buckets for memory safety. - /// - private const int DefaultLargeBufferThresholdInBytes = 8 * 1024 * 1024; - /// /// The for small-to-medium buffers which is not kept clean. /// @@ -40,7 +29,7 @@ namespace SixLabors.ImageSharp.Memory /// Initializes a new instance of the class. /// public ArrayPoolMemoryManager() - : this(DefaultMaxPooledBufferSizeInBytes, DefaultLargeBufferThresholdInBytes) + : this(DefaultMaxPooledBufferSizeInBytes, DefaultBufferSelectorThresholdInBytes) { } diff --git a/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs b/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs index 581e0b78d..f99ee4dde 100644 --- a/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs +++ b/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests.Memory private const int PoolSelectorThresholdInBytes = MaxPooledBufferSizeInBytes / 2; - private MemoryManager MemoryManager { get; } = new ArrayPoolMemoryManager(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes); + private MemoryManager MemoryManager { get; set; } = new ArrayPoolMemoryManager(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes); /// /// Rent a buffer -> return it -> re-rent -> verify if it's span points to the previous location @@ -161,5 +161,31 @@ namespace SixLabors.ImageSharp.Tests.Memory Assert.False(Unsafe.AreSame(ref ptr2Small, ref large.DangerousGetPinnableReference())); } + + [Fact] + public void CreateWithAggressivePooling() + { + this.MemoryManager = ArrayPoolMemoryManager.CreateWithAggressivePooling(); + + Assert.True(this.CheckIsRentingPooledBuffer(4096 * 4096)); + } + + [Fact] + public void CreateWithNormalPooling() + { + this.MemoryManager = ArrayPoolMemoryManager.CreateWithNormalPooling(); + + Assert.False(this.CheckIsRentingPooledBuffer(2 * 4096 * 4096)); + Assert.True(this.CheckIsRentingPooledBuffer(2048 * 2048)); + } + + [Fact] + public void CreateWithModeratePooling() + { + this.MemoryManager = ArrayPoolMemoryManager.CreateWithModeratePooling(); + + Assert.False(this.CheckIsRentingPooledBuffer(2048 * 2048)); + Assert.True(this.CheckIsRentingPooledBuffer(1024 * 16)); + } } } \ No newline at end of file