use RecyclableMemoryStream to reduce GC pressure

This commit is contained in:
13xforever 2019-12-06 16:04:47 +05:00
parent 4f268b6102
commit 214a7e5a00
15 changed files with 26 additions and 16 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.IO;
using NLog;
namespace CompatApiClient
@ -70,6 +71,7 @@ namespace CompatApiClient
}
public static readonly ILogger Log;
public static readonly RecyclableMemoryStreamManager MemoryStreamManager = new RecyclableMemoryStreamManager();
static ApiConfig()
{

View File

@ -14,6 +14,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog" Version="4.6.8" />
</ItemGroup>

View File

@ -11,7 +11,7 @@ namespace CompatApiClient.Compression
public virtual async Task<long> CompressAsync(Stream source, Stream destination)
{
using var memStream = new MemoryStream();
using var memStream = ApiConfig.MemoryStreamManager.GetStream();
using (var compressed = CreateCompressionStream(memStream))
await source.CopyToAsync(compressed).ConfigureAwait(false);
memStream.Seek(0, SeekOrigin.Begin);
@ -21,7 +21,7 @@ namespace CompatApiClient.Compression
public virtual async Task<long> DecompressAsync(Stream source, Stream destination)
{
using var memStream = new MemoryStream();
using var memStream = ApiConfig.MemoryStreamManager.GetStream();
using (var decompressed = CreateDecompressionStream(source))
await decompressed.CopyToAsync(memStream).ConfigureAwait(false);
memStream.Seek(0, SeekOrigin.Begin);

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using CompatApiClient;
using Force.Crc32;
namespace IrdLibraryClient.IrdFormat
@ -21,7 +22,7 @@ namespace IrdLibraryClient.IrdFormat
{
using var compressedStream = new MemoryStream(content, false);
using var gzip = new GZipStream(compressedStream, CompressionMode.Decompress);
using var decompressedStream = new MemoryStream();
using var decompressedStream = ApiConfig.MemoryStreamManager.GetStream();
gzip.CopyTo(decompressedStream);
content = decompressedStream.ToArray();
}

View File

@ -2,6 +2,7 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
using CompatApiClient;
using DiscUtils.Iso9660;
namespace IrdLibraryClient.IrdFormat
@ -10,7 +11,7 @@ namespace IrdLibraryClient.IrdFormat
{
public static List<string> GetFilenames(this Ird ird)
{
using var decompressedStream = new MemoryStream();
using var decompressedStream = ApiConfig.MemoryStreamManager.GetStream();
using (var compressedStream = new MemoryStream(ird.Header, false))
{
using var gzip = new GZipStream(compressedStream, CompressionMode.Decompress);

View File

@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Crc32.NET" Version="1.2.0" />
<PackageReference Include="DiscUtils.OpticalDisk" Version="0.15.1-ci0002" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.2" />
</ItemGroup>
<ItemGroup>

View File

@ -32,8 +32,8 @@ namespace PsnClient
foreach (var resource in certNames)
{
using var stream = current.GetManifestResourceStream(resource);
using var memStream = new MemoryStream();
stream.CopyTo(memStream);
using var memStream = ApiConfig.MemoryStreamManager.GetStream();
stream?.CopyTo(memStream);
var cert = new X509Certificate2(memStream.ToArray());
var cn = cert.GetNameInfo(X509NameType.SimpleName, false);
if ((cn?.StartsWith("SCEI DNAS Root") ?? false))

View File

@ -15,6 +15,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.2" />
</ItemGroup>
<ItemGroup>

View File

@ -22,8 +22,8 @@ namespace CompatBot.Commands.Attributes
if (ctx.Channel.IsPrivate || help)
return true;
using (var stream = new MemoryStream(Poster.Value))
await ctx.RespondWithFileAsync("senpai_plz.jpg", stream).ConfigureAwait(false);
using var stream = new MemoryStream(Poster.Value);
await ctx.RespondWithFileAsync("senpai_plz.jpg", stream).ConfigureAwait(false);
return false;
}
}

View File

@ -46,8 +46,8 @@ namespace CompatBot.Commands
{
await ctx.ReactWithAsync(Config.Reactions.PleaseWait).ConfigureAwait(false);
var members = GetMembers(ctx.Client);
using var compressedResult = new MemoryStream();
using (var memoryStream = new MemoryStream())
using var compressedResult = Config.MemoryStreamManager.GetStream();
using (var memoryStream = Config.MemoryStreamManager.GetStream())
{
using (var writer = new StreamWriter(memoryStream, new UTF8Encoding(false), 4096, true))
{
@ -204,8 +204,8 @@ namespace CompatBot.Commands
checkedMembers.Add(member);
}
using var compressedStream = new MemoryStream();
using var uncompressedStream = new MemoryStream();
using var compressedStream = Config.MemoryStreamManager.GetStream();
using var uncompressedStream = Config.MemoryStreamManager.GetStream();
using (var writer = new StreamWriter(uncompressedStream, new UTF8Encoding(false), 4096, true))
{
writer.Write(result.ToString());

View File

@ -111,7 +111,7 @@ namespace CompatBot.Commands
var logPath = Config.CurrentLogPath;
var attachmentSizeLimit = Config.AttachmentSizeLimit;
using var log = File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var result = new MemoryStream((int)Math.Min(attachmentSizeLimit, log.Length));
using var result = Config.MemoryStreamManager.GetStream();
using (var gzip = new GZipStream(result, CompressionLevel.Optimal, true))
{
await log.CopyToAsync(gzip, Config.Cts.Token).ConfigureAwait(false);

View File

@ -71,7 +71,7 @@ namespace CompatBot.Commands
await ctx.SendAutosplitMessageAsync(result.Append("```")).ConfigureAwait(false);
if (bigList)
{
using var memoryStream = new MemoryStream((int)(fullList.Capacity*1.25));
using var memoryStream = Config.MemoryStreamManager.GetStream();
using var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8);
await streamWriter.WriteAsync(fullList).ConfigureAwait(false);
await streamWriter.FlushAsync().ConfigureAwait(false);

View File

@ -44,6 +44,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.2" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.5" />
<PackageReference Include="Nerdbank.Streams" Version="2.4.46" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />

View File

@ -10,6 +10,7 @@ using DSharpPlus.Entities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Logging;
using Microsoft.IO;
using NLog;
using NLog.Extensions.Logging;
using NLog.Filters;
@ -26,6 +27,7 @@ namespace CompatBot
internal static readonly ILogger Log;
internal static readonly ILoggerFactory LoggerFactory;
internal static readonly ConcurrentDictionary<string, string> inMemorySettings = new ConcurrentDictionary<string, string>();
internal static readonly RecyclableMemoryStreamManager MemoryStreamManager = new RecyclableMemoryStreamManager();
public static readonly CancellationTokenSource Cts = new CancellationTokenSource();
public static readonly TimeSpan ModerationTimeThreshold = TimeSpan.FromHours(12);

View File

@ -163,7 +163,7 @@ namespace CompatBot.Database.Providers
return (url, null);
using var imgStream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false);
using var memStream = new MemoryStream();
using var memStream = Config.MemoryStreamManager.GetStream();
await imgStream.CopyToAsync(memStream).ConfigureAwait(false);
// minimum jpg size is 119 bytes, png is 67 bytes
if (memStream.Length < 64)
@ -190,7 +190,7 @@ namespace CompatBot.Database.Providers
return null;
using var imgStream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false);
using var memStream = new MemoryStream();
using var memStream = Config.MemoryStreamManager.GetStream();
await imgStream.CopyToAsync(memStream).ConfigureAwait(false);
// minimum jpg size is 119 bytes, png is 67 bytes
if (memStream.Length < 64)