Browse Source

Slight perf tweak plus duplicate refactoring

af/merge-core
James Jackson-South 8 years ago
parent
commit
a4f3392013
  1. 128
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs

128
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs

@ -4,6 +4,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
// TODO: This could be useful elsewhere. // 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 ChunkLengthMinusOne = ChunkLength - 1;
private const int ChunkLengthPlusOne = ChunkLength + 1;
private readonly Stream stream; private readonly Stream stream;
private readonly IManagedByteBuffer buffer; private readonly IManagedByteBuffer managedBuffer;
private readonly byte[] bufferChunk; private readonly byte[] bufferChunk;
private readonly int length;
private int bytesRead; private int bytesRead;
private int position; private int position;
private int length;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DoubleBufferedStreamReader"/> class. /// Initializes a new instance of the <see cref="DoubleBufferedStreamReader"/> class.
/// </summary> /// </summary>
@ -45,8 +44,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{ {
this.stream = stream; this.stream = stream;
this.length = (int)stream.Length; this.length = (int)stream.Length;
this.buffer = memoryManager.AllocateCleanManagedByteBuffer(ChunkLength); this.managedBuffer = memoryManager.AllocateCleanManagedByteBuffer(ChunkLength);
this.bufferChunk = this.buffer.Array; this.bufferChunk = this.managedBuffer.Array;
} }
/// <summary> /// <summary>
@ -86,11 +85,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{ {
return this.ReadByteSlow(); return this.ReadByteSlow();
} }
else
{ this.position++;
this.position++; return this.bufferChunk[this.bytesRead++];
return this.bufferChunk[this.bytesRead++];
}
} }
/// <summary> /// <summary>
@ -125,53 +122,29 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Read(byte[] buffer, int offset, int count) 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.ReadToBufferSlow(buffer, offset, count);
{ }
return this.ReadToChunkSlow(buffer, offset, count);
}
int n = this.length - this.position;
if (n > count)
{
n = count;
}
if (n < 0)
{
n = 0;
}
if (n < 9) if (this.position == 0 || count + this.bytesRead > ChunkLength)
{ {
int byteCount = n; return this.ReadToChunkSlow(buffer, offset, count);
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);
}
this.position += n; int n = this.GetCount(count);
this.bytesRead += n; this.CopyBytes(buffer, offset, n);
return n; this.position += n;
} this.bytesRead += n;
return this.ReadToBufferSlow(buffer, offset, count); return n;
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
this.buffer?.Dispose(); this.managedBuffer?.Dispose();
} }
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
@ -201,6 +174,32 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
this.stream.Read(this.bufferChunk, 0, ChunkLength); this.stream.Read(this.bufferChunk, 0, ChunkLength);
this.bytesRead = 0; 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; int n = this.length - this.position;
if (n > count) if (n > count)
{ {
@ -212,9 +211,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
n = 0; 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; int read = this.bytesRead;
byte[] chunk = this.bufferChunk; byte[] chunk = this.bufferChunk;
@ -225,27 +230,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
} }
else 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;
} }
} }
} }
Loading…
Cancel
Save