From a4f3392013b3dc03576101da16dbba2aa3b9861f Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 30 Apr 2018 00:06:16 +1000 Subject: [PATCH] Slight perf tweak plus duplicate refactoring --- .../Components/DoubleBufferedStreamReader.cs | 128 ++++++++---------- 1 file changed, 57 insertions(+), 71 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs index 90f55bc5d..164ca7cc1 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Runtime.CompilerServices; + using SixLabors.ImageSharp.Memory; // TODO: This could be useful elsewhere. @@ -22,20 +23,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components private const int ChunkLengthMinusOne = ChunkLength - 1; - private const int ChunkLengthPlusOne = ChunkLength + 1; - private readonly Stream stream; - private readonly IManagedByteBuffer buffer; + private readonly IManagedByteBuffer managedBuffer; private readonly byte[] bufferChunk; + private readonly int length; + private int bytesRead; private int position; - private int length; - /// /// Initializes a new instance of the class. /// @@ -45,8 +44,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components { this.stream = stream; this.length = (int)stream.Length; - this.buffer = memoryManager.AllocateCleanManagedByteBuffer(ChunkLength); - this.bufferChunk = this.buffer.Array; + this.managedBuffer = memoryManager.AllocateCleanManagedByteBuffer(ChunkLength); + this.bufferChunk = this.managedBuffer.Array; } /// @@ -86,11 +85,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components { return this.ReadByteSlow(); } - else - { - this.position++; - return this.bufferChunk[this.bytesRead++]; - } + + this.position++; + return this.bufferChunk[this.bytesRead++]; } /// @@ -125,53 +122,29 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Read(byte[] buffer, int offset, int count) { - if (buffer.Length < ChunkLengthPlusOne) + if (buffer.Length > ChunkLength) { - if (this.position == 0 || count + this.bytesRead > ChunkLength) - { - return this.ReadToChunkSlow(buffer, offset, count); - } - - int n = this.length - this.position; - if (n > count) - { - n = count; - } - - if (n < 0) - { - n = 0; - } + return this.ReadToBufferSlow(buffer, offset, count); + } - if (n < 9) - { - int byteCount = n; - int read = this.bytesRead; - byte[] chunk = this.bufferChunk; - - while (--byteCount > -1) - { - buffer[offset + byteCount] = chunk[read + byteCount]; - } - } - else - { - Buffer.BlockCopy(this.bufferChunk, this.bytesRead, buffer, offset, n); - } + if (this.position == 0 || count + this.bytesRead > ChunkLength) + { + return this.ReadToChunkSlow(buffer, offset, count); + } - this.position += n; - this.bytesRead += n; + int n = this.GetCount(count); + this.CopyBytes(buffer, offset, n); - return n; - } + this.position += n; + this.bytesRead += n; - return this.ReadToBufferSlow(buffer, offset, count); + return n; } /// public void Dispose() { - this.buffer?.Dispose(); + this.managedBuffer?.Dispose(); } [MethodImpl(MethodImplOptions.NoInlining)] @@ -201,6 +174,32 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components this.stream.Read(this.bufferChunk, 0, ChunkLength); this.bytesRead = 0; + int n = this.GetCount(count); + this.CopyBytes(buffer, offset, n); + + this.position += n; + this.bytesRead += n; + + return n; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private int ReadToBufferSlow(byte[] buffer, int offset, int count) + { + // Read to target but don't copy to our chunk. + if (this.position != this.stream.Position) + { + this.stream.Seek(this.position, SeekOrigin.Begin); + } + + int n = this.stream.Read(buffer, offset, count); + this.Position += n; + return n; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private int GetCount(int count) + { int n = this.length - this.position; if (n > count) { @@ -212,9 +211,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components n = 0; } - if (n < 9) + return n; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyBytes(byte[] buffer, int offset, int count) + { + if (count < 9) { - int byteCount = n; + int byteCount = count; int read = this.bytesRead; byte[] chunk = this.bufferChunk; @@ -225,27 +230,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components } else { - Buffer.BlockCopy(this.bufferChunk, this.bytesRead, buffer, offset, n); + Buffer.BlockCopy(this.bufferChunk, this.bytesRead, buffer, offset, count); } - - this.position += n; - this.bytesRead += n; - - return n; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private int ReadToBufferSlow(byte[] buffer, int offset, int count) - { - // Read to target but don't copy to our chunk. - if (this.position != this.stream.Position) - { - this.stream.Seek(this.position, SeekOrigin.Begin); - } - - int n = this.stream.Read(buffer, offset, count); - this.Position += n; - return n; } } } \ No newline at end of file