MemoryStream optimizations

This commit is contained in:
Bond_009 2020-08-07 17:38:01 +02:00 committed by Bond-009
parent 75bb127599
commit 371a09c60b
7 changed files with 36 additions and 26 deletions

View File

@ -1,3 +1,5 @@
#nullable enable
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -22,7 +24,7 @@ namespace Emby.Server.Implementations.AppBase
{ {
object configuration; object configuration;
byte[] buffer = null; byte[]? buffer = null;
// Use try/catch to avoid the extra file system lookup using File.Exists // Use try/catch to avoid the extra file system lookup using File.Exists
try try
@ -36,19 +38,23 @@ namespace Emby.Server.Implementations.AppBase
configuration = Activator.CreateInstance(type); configuration = Activator.CreateInstance(type);
} }
using var stream = new MemoryStream(); using var stream = new MemoryStream(buffer?.Length ?? 0);
xmlSerializer.SerializeToStream(configuration, stream); xmlSerializer.SerializeToStream(configuration, stream);
// Take the object we just got and serialize it back to bytes // Take the object we just got and serialize it back to bytes
var newBytes = stream.ToArray(); byte[] newBytes = stream.GetBuffer();
int newBytesLen = (int)stream.Length;
// If the file didn't exist before, or if something has changed, re-save // If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !buffer.SequenceEqual(newBytes)) if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer))
{ {
Directory.CreateDirectory(Path.GetDirectoryName(path)); Directory.CreateDirectory(Path.GetDirectoryName(path));
// Save it after load in case we got new items // Save it after load in case we got new items
File.WriteAllBytes(path, newBytes); using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
{
fs.Write(newBytes, 0, newBytesLen);
}
} }
return configuration; return configuration;

View File

@ -105,7 +105,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>(); responseHeaders = new Dictionary<string, string>();
} }
if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string expires)) if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out _))
{ {
responseHeaders[HeaderNames.Expires] = "0"; responseHeaders[HeaderNames.Expires] = "0";
} }
@ -326,7 +326,8 @@ namespace Emby.Server.Implementations.HttpServer
return GetHttpResult(request, ms, contentType, true, responseHeaders); return GetHttpResult(request, ms, contentType, true, responseHeaders);
} }
private IHasHeaders GetCompressedResult(byte[] content, private IHasHeaders GetCompressedResult(
byte[] content,
string requestedCompressionType, string requestedCompressionType,
IDictionary<string, string> responseHeaders, IDictionary<string, string> responseHeaders,
bool isHeadRequest, bool isHeadRequest,

View File

@ -95,13 +95,13 @@ namespace Emby.Server.Implementations.HttpServer
if (bytes != null) if (bytes != null)
{ {
await responseStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false); await responseStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false);
} }
else else
{ {
using (var src = SourceStream) using (var src = SourceStream)
{ {
await src.CopyToAsync(responseStream).ConfigureAwait(false); await src.CopyToAsync(responseStream, cancellationToken).ConfigureAwait(false);
} }
} }
} }

View File

@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Serialization
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public object DeserializeFromBytes(Type type, byte[] buffer) public object DeserializeFromBytes(Type type, byte[] buffer)
{ {
using (var stream = new MemoryStream(buffer)) using (var stream = new MemoryStream(buffer, 0, buffer.Length, false, true))
{ {
return DeserializeFromStream(type, stream); return DeserializeFromStream(type, stream);
} }

View File

@ -969,7 +969,7 @@ namespace Jellyfin.Api.Controllers
var text = await reader.ReadToEndAsync().ConfigureAwait(false); var text = await reader.ReadToEndAsync().ConfigureAwait(false);
var bytes = Convert.FromBase64String(text); var bytes = Convert.FromBase64String(text);
return new MemoryStream(bytes) { Position = 0 }; return new MemoryStream(bytes, 0, bytes.Length, false, true);
} }
private ImageInfo? GetImageInfo(BaseItem item, ItemImageInfo info, int? imageIndex) private ImageInfo? GetImageInfo(BaseItem item, ItemImageInfo info, int? imageIndex)

View File

@ -124,6 +124,8 @@ namespace MediaBrowser.Providers.Manager
var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false); var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
// If there are more than one output paths, the stream will need to be seekable // If there are more than one output paths, the stream will need to be seekable
if (paths.Length > 1 && !source.CanSeek)
{
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
await using (source.ConfigureAwait(false)) await using (source.ConfigureAwait(false))
{ {
@ -131,6 +133,7 @@ namespace MediaBrowser.Providers.Manager
} }
source = memoryStream; source = memoryStream;
}
var currentImage = GetCurrentImage(item, type, index); var currentImage = GetCurrentImage(item, type, index);
var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile; var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile;
@ -140,20 +143,21 @@ namespace MediaBrowser.Providers.Manager
await using (source.ConfigureAwait(false)) await using (source.ConfigureAwait(false))
{ {
var currentPathIndex = 0; for (int i = 0; i < paths.Length; i++)
{
foreach (var path in paths) if (i != 0)
{ {
source.Position = 0; source.Position = 0;
}
string retryPath = null; string retryPath = null;
if (paths.Length == retryPaths.Length) if (paths.Length == retryPaths.Length)
{ {
retryPath = retryPaths[currentPathIndex]; retryPath = retryPaths[i];
} }
var savedPath = await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); var savedPath = await SaveImageToLocation(source, paths[i], retryPath, cancellationToken).ConfigureAwait(false);
savedPaths.Add(savedPath); savedPaths.Add(savedPath);
currentPathIndex++;
} }
} }
@ -224,7 +228,6 @@ namespace MediaBrowser.Providers.Manager
} }
} }
source.Position = 0;
await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false); await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false);
return retryPath; return retryPath;
} }
@ -253,7 +256,7 @@ namespace MediaBrowser.Providers.Manager
await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous)) await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
{ {
await source.CopyToAsync(fs, IODefaults.CopyToBufferSize, cancellationToken).ConfigureAwait(false); await source.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
} }
if (_config.Configuration.SaveMetadataHidden) if (_config.Configuration.SaveMetadataHidden)

View File

@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Subtitles
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var parts = subtitleId.Split(new[] { '_' }, 2); var parts = subtitleId.Split(new[] { '_' }, 2);
var provider = GetProvider(parts.First()); var provider = GetProvider(parts[0]);
var saveInMediaFolder = libraryOptions.SaveSubtitlesWithMedia; var saveInMediaFolder = libraryOptions.SaveSubtitlesWithMedia;